Professional Documents
Culture Documents
Borland ® ™
Delphi 5
pour Windows 98, Windows 95, Windows NT
Reportez-vous au fichier DEPLOY.TXT situé dans le répertoire racine de votre produit Delphi 5 pour obtenir la
liste complète des fichiers que vous pouvez distribuer en accord avec les termes du contrat de licence.
Les applications mentionnées dans ce manuel sont brevetées ou en attente de brevet. Ce document ne donne
aucun droit sur ces brevets.
COPYRIGHT © 1983, 1999 Inprise Corporation. Tous droits réservés. Tous les produits Inprise et Borland sont des
marques ou des marques déposées de Inprise Corporation. Tous les autres noms de produits sont des marques
déposées de leurs fabricants respectifs.
Imprimé en Irlande
HDE1350WW21001 3E2R799
9900010203-9 8 7 6 5 4 3 2 1
D3
Table des matières
Chapitre 1 Génération d’un nouveau gestionnaire
d’événement. . . . . . . . . . . . . . . . . . 2-28
Introduction 1-1 Génération du gestionnaire de l’événe-
Contenu de ce manuel . . . . . . . . . . . . . .1-1 ment par défaut d’un composant. . . . . 2-28
Conventions typographiques. . . . . . . . . . .1-3 Recherche de gestionnaires
d’événements . . . . . . . . . . . . . . . . . 2-29
Support technique Inprise . . . . . . . . . . . .1-3 Association d’un événement à un
gestionnaire d’événement existant . . . . 2-29
Partie I Association d’événements de menu à des
Programmation avec Delphi gestionnaires d’événements . . . . . . . .
Suppression de gestionnaires
2-30
d’événements . . . . . . . . . . . . . . . . . 2-31
Chapitre 2 Emploi d’objets utilitaires . . . . . . . . . . . . 2-31
Utilisation du Pascal Objet Utilisation des listes. . . . . . . . . . . . . . . 2-31
avec la VCL 2-1 Utilisation des listes de chaînes . . . . . . . 2-32
Chargement et enregistrement de listes
Pascal Objet et VCL . . . . . . . . . . . . . . . .2-1 de chaînes . . . . . . . . . . . . . . . . . . . 2-32
Utilisation du modèle objet . . . . . . . . . . .2-2 Création d’une nouvelle liste de chaînes . 2-33
Qu’est-ce qu’un objet ? . . . . . . . . . . . . . 2-2 Manipulation des chaînes d’une liste . . . 2-35
Examen d’un objet Delphi . . . . . . . . . . . 2-3 Association d’objets à une liste de
Héritage des données et du code d’un chaînes . . . . . . . . . . . . . . . . . . . . . 2-37
objet . . . . . . . . . . . . . . . . . . . . . . . . 2-6 Le registre et les fichiers INI Windows . . . 2-37
Objets, composants et contrôles. . . . . . . . 2-6 Utilisation des flux . . . . . . . . . . . . . . . 2-38
Portée et qualificateurs . . . . . . . . . . . . . 2-7 Utilisation de modules de données et de
Déclarations privées, protégées, publiques modules de données distants . . . . . . . . 2-38
et publiées. . . . . . . . . . . . . . . . . . . . 2-8 Création et modification de modules de
Utilisation de variables objet. . . . . . . . . . 2-8 données . . . . . . . . . . . . . . . . . . . . . 2-38
Création, instanciation et destruction Création de règles de gestion dans un
d’objets . . . . . . . . . . . . . . . . . . . . . . 2-9 module de données . . . . . . . . . . . . . 2-39
Composants et appartenance . . . . . . . . 2-10 Accès à un module de données depuis une
Utilisation des composants . . . . . . . . . . . 2-10 fiche . . . . . . . . . . . . . . . . . . . . . . . 2-39
Composants standard de Delphi . . . . . . . 2-11 Ajout d’un module de données distant à
Propriétés communes à tous les un projet serveur d’application . . . . . . . 2-40
composants . . . . . . . . . . . . . . . . . . 2-11 Utilisation du référentiel d’objets . . . . . . . 2-40
Contrôles texte . . . . . . . . . . . . . . . . . 2-13 Partage d’éléments dans un projet. . . . . . 2-40
Contrôles de saisies spécialisées . . . . . . 2-15 Ajout d’éléments au référentiel d’objets . . 2-41
Contrôles bouton et similaires . . . . . . . 2-16 Partage d’objets par une équipe de
Gestion de listes . . . . . . . . . . . . . . . . 2-19 développement. . . . . . . . . . . . . . . . . 2-41
Regroupement de composants . . . . . . . 2-21 Utilisation d’un élément du référentiel
Rétroaction visuelle . . . . . . . . . . . . . . 2-22 d’objets dans un projet . . . . . . . . . . . . 2-41
Grilles . . . . . . . . . . . . . . . . . . . . . . 2-24 Copie d’un élément . . . . . . . . . . . . . . 2-42
Affichage graphique. . . . . . . . . . . . . . 2-25 Héritage d’un élément . . . . . . . . . . . . 2-42
Boîtes de dialogue standard Windows . . 2-26 Utilisation d’un élément . . . . . . . . . . . 2-42
Initialisation des propriétés d’un Utilisation de modèles de projet . . . . . . . 2-42
composant . . . . . . . . . . . . . . . . . . . . 2-26 Modification d’éléments partagés . . . . . . 2-43
Utilisation de l’inspecteur d’objet . . . . . 2-26 Spécification d’un projet par défaut, d’une
Initialisation des propriétés à l’exécution . 2-27 nouvelle fiche et de la fiche principale . . 2-43
Appel de méthodes . . . . . . . . . . . . . . . 2-27 Ajout de composants personnalisés à
Utilisation des événements et des l’EDI . . . . . . . . . . . . . . . . . . . . . . . . 2-43
gestionnaires d’événements . . . . . . . . . 2-28
i
Chapitre 3 Routines de la bibliothèque d’exécution
manipulant des chaînes . . . . . . . . . . . 3-29
Sujets de programmation généraux 3-1 Routines manipulant les caractères
Gestion des exceptions . . . . . . . . . . . . . .3-1 étendus. . . . . . . . . . . . . . . . . . . . . 3-29
Protection des blocs de code. . . . . . . . . . 3-2 Routines usuelles de manipulation des
Réponse aux exceptions . . . . . . . . . . . . 3-2 chaînes longues. . . . . . . . . . . . . . . . 3-30
Exceptions et contrôle d’exécution . . . . . . 3-3 Déclaration et initialisation de chaînes . . . 3-32
Réponses à des exceptions imbriquées . . . 3-3 Mélange et conversion de types chaîne. . . 3-33
Protection de l’allocation de ressources . . . 3-4 Conversions de chaînes en PChar . . . . . . 3-33
Quelles ressources doivent être protégées ? . 3-4 Dépendances de chaîne. . . . . . . . . . . . 3-34
Création d’un bloc de protection de Renvoi d’une variable locale PChar . . . . 3-34
ressource. . . . . . . . . . . . . . . . . . . . . 3-5 Transfert d’une variable locale comme
Gestion des exceptions RTL . . . . . . . . . . 3-6 PChar. . . . . . . . . . . . . . . . . . . . . . 3-34
Qu’est-ce qu’une exception RTL ? . . . . . . 3-6 Directives de compilation portant sur les
Création d’un gestionnaire d’exception . . . 3-7 chaînes. . . . . . . . . . . . . . . . . . . . . . 3-35
Instructions de gestion des exceptions . . . 3-8 Chaînes et caractères : sujets apparentés . . 3-36
Utilisation de l’instance d’exception . . . . . 3-9 Utilisation des fichiers . . . . . . . . . . . . . . 3-36
Portée des gestionnaires d’exceptions . . . . 3-9 Manipulation de fichiers . . . . . . . . . . . . 3-37
Spécification du gestionnaire d’exception Suppression d’un fichier . . . . . . . . . . . 3-37
par défaut . . . . . . . . . . . . . . . . . . . 3-10 Recherche d’un fichier . . . . . . . . . . . . 3-37
Gestion des classes d’exceptions . . . . . . 3-10 Modifications des attributs d’un fichier . . 3-39
Redéclenchement de l’exception . . . . . . 3-11 Modification d’un nom de fichier . . . . . 3-39
Gestion des exceptions des composants . . . 3-12 Routines date-heure de fichier. . . . . . . . 3-40
Utilisation de Copie d’un fichier . . . . . . . . . . . . . . . 3-40
TApplication.HandleException. . . . . . . . 3-13 Types fichier et E/S de fichier . . . . . . . . 3-40
Exceptions silencieuses . . . . . . . . . . . . . 3-13 Utilisation des flux fichier . . . . . . . . . . . 3-41
Définition d’exceptions personnalisées. . . . 3-14 Création et ouverture de fichiers . . . . . . 3-41
Déclaration d’un type objet exception. . . 3-14 Utilisation du handle de fichier . . . . . . . 3-42
Déclenchement d’une exception . . . . . . 3-15 Lecture et écriture de fichiers . . . . . . . . 3-42
Utilisation des interfaces . . . . . . . . . . . . 3-15 Lecture et écriture de chaînes . . . . . . . . 3-43
Création d’interfaces. . . . . . . . . . . . . . . 3-15 Déplacements dans un fichier . . . . . . . . 3-44
Partage d’interfaces entre des classes . . . 3-16 Position et taille de fichier . . . . . . . . . . 3-44
Utilisation d’interfaces avec des Copie . . . . . . . . . . . . . . . . . . . . . . . 3-45
procédures . . . . . . . . . . . . . . . . . . 3-17 Définition de nouveaux types de données . 3-45
Implémentation de IUnknown . . . . . . . . 3-18
TInterfacedObject. . . . . . . . . . . . . . . . . 3-19 Chapitre 4
Utilisation de l’opérateur as . . . . . . . . . . 3-19 Création d’applications,
Réutilisation de code et délégation . . . . . . 3-20
Utilisation de implements pour la de composants
délégation . . . . . . . . . . . . . . . . . . . 3-20 et de bibliothèques 4-1
Agrégation . . . . . . . . . . . . . . . . . . . 3-21
Gestion mémoire des objets interface . . . . 3-22 Création d’applications . . . . . . . . . . . . . 4-1
Utilisation du comptage de références . . 3-22 Applications Windows . . . . . . . . . . . . . . 4-1
Situations où il ne faut pas utiliser le Modèles d’interfaces utilisateur . . . . . . . . 4-2
comptage de références. . . . . . . . . . . 3-24 Définition des options de l’EDI, du projet
Utilisation d’interfaces dans des et de la compilation . . . . . . . . . . . . . . 4-2
applications distribuées . . . . . . . . . . . . 3-24 Modèles de programmation. . . . . . . . . . . 4-3
Utilisation des chaînes. . . . . . . . . . . . . . 3-25 Applications console . . . . . . . . . . . . . . . 4-3
Types caractère . . . . . . . . . . . . . . . . . . 3-25 Applications service. . . . . . . . . . . . . . . . 4-3
Types chaîne. . . . . . . . . . . . . . . . . . . . 3-26 Threads de service . . . . . . . . . . . . . . . . 4-6
Chaînes courtes . . . . . . . . . . . . . . . . 3-26 Propriétés de nom d’un service. . . . . . . . 4-8
Chaînes longues . . . . . . . . . . . . . . . . 3-27 Débogage des services . . . . . . . . . . . . . 4-8
Chaînes étendues . . . . . . . . . . . . . . . 3-28 Création de paquets et de DLL . . . . . . . . 4-9
Types PChar . . . . . . . . . . . . . . . . . . 3-28 Utilisation des paquets et des DLL . . . . . . 4-9
Chaînes ouvertes. . . . . . . . . . . . . . . . 3-29 Ecriture d'applications de base de données . . 4-10
ii
Conception d’applications distribuées . . . . 4-10 Création et gestion de menus . . . . . . . . . 5-16
Distribution d’applications en utilisant Ouverture du concepteur de menus. . . . . 5-17
TCP / IP . . . . . . . . . . . . . . . . . . . . . 4-11 Conception de menus . . . . . . . . . . . . . 5-19
Utilisation de sockets dans les Nom des menus . . . . . . . . . . . . . . . . 5-19
applications . . . . . . . . . . . . . . . . . . 4-11 Nom des éléments de menu. . . . . . . . . 5-19
Création d’applications serveur Web . . . 4-11 Ajout, insertion et suppression d’éléments
Distribution d’applications en utilisant de menu . . . . . . . . . . . . . . . . . . . . 5-20
COM et DCOM. . . . . . . . . . . . . . . . . 4-12 Création de sous-menus . . . . . . . . . . . 5-22
COM et DCOM . . . . . . . . . . . . . . . . 4-12 Affichage du menu . . . . . . . . . . . . . . 5-24
MTS . . . . . . . . . . . . . . . . . . . . . . . 4-12 Edition des éléments de menu dans
Distribution d’applications en utilisant l’inspecteur d’objets . . . . . . . . . . . . . . 5-24
CORBA. . . . . . . . . . . . . . . . . . . . . . 4-13 Utilisation du menu contextuel du
Distribution d’applications de base de concepteur de menus . . . . . . . . . . . . . 5-25
données. . . . . . . . . . . . . . . . . . . . . . 4-13 Commandes du menu contextuel . . . . . 5-25
Changement de menu à la conception . . 5-26
Chapitre 5 Utilisation des modèles de menu . . . . . . 5-27
Conception de l’interface utilisateur Enregistrement d’un menu comme
modèle. . . . . . . . . . . . . . . . . . . . . . 5-28
des applications 5-1 Conventions de nom pour les éléments
TApplication, TScreen et TForm. . . . . . . . .5-1 et les gestionnaires d’événements des
Utilisation de la fiche principale . . . . . . . 5-1 modèles de menu . . . . . . . . . . . . . . 5-29
Ajout de fiches supplémentaires . . . . . . . 5-2 Manipulation d’éléments de menu à
Liaison de fiches . . . . . . . . . . . . . . . . . 5-2 l’exécution. . . . . . . . . . . . . . . . . . . . 5-29
Manipulation de l’application . . . . . . . . . 5-3 Fusion de menus . . . . . . . . . . . . . . . . 5-30
Gestion de l’écran . . . . . . . . . . . . . . . . 5-3 Spécification du menu actif : propriété
Menu . . . . . . . . . . . . . . . . . . . . . . 5-30
Gestion de la disposition . . . . . . . . . . . . 5-3 Ordre des éléments de menu fusionnés :
Utilisation des messages . . . . . . . . . . . . .5-4 propriété GroupIndex . . . . . . . . . . . . 5-30
Informations supplémentaires sur les fiches . .5-5 Importation de fichiers ressource . . . . . . 5-31
Contrôle du stockage en mémoire des Conception de barres d’outils et de barres
fiches . . . . . . . . . . . . . . . . . . . . . . . 5-5 multiples . . . . . . . . . . . . . . . . . . . . . 5-31
Affichage d’une fiche créée Ajout d’une barre d’outils en utilisant un
automatiquement . . . . . . . . . . . . . . . 5-6 composant volet . . . . . . . . . . . . . . . . 5-32
Création dynamique de fiche . . . . . . . . . 5-6 Ajout d’un turbobouton à un volet . . . . 5-33
Création de fiches non modales comme Spécification du glyphe d’un
fenêtres. . . . . . . . . . . . . . . . . . . . . . 5-7 turbobouton . . . . . . . . . . . . . . . . . . 5-33
Utilisation d’une variable locale pour créer Définition de l’état initial d’un
une instance de fiche . . . . . . . . . . . . . 5-7 turbobouton . . . . . . . . . . . . . . . . . . 5-33
Transfert de paramètres supplémentaires Création d’un groupe de turboboutons . . 5-34
aux fiches . . . . . . . . . . . . . . . . . . . . 5-8 Utilisation de boutons bascule . . . . . . . 5-34
Récupération de données des fiches . . . . . 5-9 Ajout d’une barre d’outils en utilisant le
Récupération de données dans des fiches composant barre d’outils. . . . . . . . . . . 5-34
non modales . . . . . . . . . . . . . . . . . . 5-9 Ajout d’un bouton outil . . . . . . . . . . . 5-35
Récupération de données dans des fiches Affectation d’images à des boutons
modales . . . . . . . . . . . . . . . . . . . . 5-10 outils . . . . . . . . . . . . . . . . . . . . . . 5-35
Réutilisation des composants et des Définition de l’aspect et de l’état initial
groupes de composants . . . . . . . . . . . . 5-12 d’un bouton outil . . . . . . . . . . . . . . 5-36
Création et utilisation des modèles de Création de groupes de boutons outils . . 5-36
composants . . . . . . . . . . . . . . . . . . . 5-13 Utilisation de boutons outils bascule. . . . 5-36
Manipulation des cadres . . . . . . . . . . . . 5-14 Ajout d’un composant barre multiple. . . . 5-37
Création des cadres . . . . . . . . . . . . . . . 5-14 Initialisation de l’aspect de la barre
Ajout de cadres à la palette de multiple . . . . . . . . . . . . . . . . . . . . 5-37
composants . . . . . . . . . . . . . . . . . . 5-14 Réponse aux clics . . . . . . . . . . . . . . . . 5-38
Utilisation et modification des cadres . . . . 5-15 Affectation d’un menu à un bouton outil . . 5-38
Partage des cadres . . . . . . . . . . . . . . . . 5-16 Ajout de barres d’outils masquées. . . . . . 5-38
Affichage d’une barre d’outils . . . . . . . . 5-38
iii
Utilisation des listes d’actions . . . . . . . . . 5-39 Gestion de l’événement OnPopup . . . . . . 6-12
Objets action . . . . . . . . . . . . . . . . . . . 5-39 Ajout de graphiques à des contrôles . . . . . 6-13
Utilisation des actions . . . . . . . . . . . . . . 5-41 Choix du style dessiné par le propriétaire . 6-13
Centralisation du code . . . . . . . . . . . . 5-41 Ajout d’objets graphiques à une liste de
Liaison de propriétés . . . . . . . . . . . . . 5-41 chaînes. . . . . . . . . . . . . . . . . . . . . . 6-14
Exécution d’actions . . . . . . . . . . . . . . 5-42 Ajout d’images à une application . . . . . 6-14
Actualisation des actions . . . . . . . . . . . 5-44 Ajout d’images à une liste de chaînes . . . 6-14
Classes d’actions prédéfinies. . . . . . . . . . 5-44 Dessiner des éléments dessinés par le
Actions standard d’édition. . . . . . . . . . 5-44 propriétaire . . . . . . . . . . . . . . . . . . 6-15
Actions standard de fenêtre . . . . . . . . . 5-45 Dimensionnement des éléments dessinés
Actions d’aide standard . . . . . . . . . . . 5-45 par le propriétaire . . . . . . . . . . . . . . . 6-15
Actions des ensembles de données . . . . 5-45 Dessin de chaque élément dessiné par le
Conception de composants utilisant des propriétaire . . . . . . . . . . . . . . . . . . . 6-17
actions . . . . . . . . . . . . . . . . . . . . . . 5-46
Comment les actions trouvent leurs Chapitre 7
cibles . . . . . . . . . . . . . . . . . . . . . . 5-46 Utilisation des graphiques et du
Recensement d’actions . . . . . . . . . . . . 5-48
Ecriture d’éditeurs de listes d’actions . . . 5-48 multimédia 7-1
Programmes exemple . . . . . . . . . . . . . . 5-48 Présentation de la programmation relative
aux graphiques . . . . . . . . . . . . . . . . . 7-1
Chapitre 6 Rafraîchissement de l’écran . . . . . . . . . . . 7-2
Manipulation des contrôles 6-1 Types des objets graphiques . . . . . . . . . . 7-3
Implémentation du glisser-déplacer dans Propriétés et méthodes communes du
canevas . . . . . . . . . . . . . . . . . . . . . . 7-4
les contrôles . . . . . . . . . . . . . . . . . . . .6-1
Utilisation des propriétés de l’objet canevas . 7-5
Début de l’opération glisser-déplacer . . . . 6-1
Utilisation des crayons . . . . . . . . . . . . . 7-5
Acceptation des éléments à déplacer. . . . . 6-2 Utilisation des pinceaux . . . . . . . . . . . . 7-8
Déplacement des éléments . . . . . . . . . . . 6-3 Lecture et définition de pixels. . . . . . . . . 7-9
Fin de l’opération glisser-déplacer . . . . . . 6-3 Utilisation des méthodes du canevas pour
Personnalisation du glisser-déplacer avec dessiner des objets graphiques . . . . . . . 7-10
un objet déplacement . . . . . . . . . . . . . 6-4 Dessin de lignes et de polylignes. . . . . . 7-10
Changement du pointeur de la souris . . . . 6-4 Dessin de formes. . . . . . . . . . . . . . . . 7-11
Implémentation du glisser-empiler dans Gestion de plusieurs objets de dessin dans
les contrôles . . . . . . . . . . . . . . . . . . . .6-4 votre application. . . . . . . . . . . . . . . . 7-12
Transformation d’un contrôle fenêtré en un Faire le suivi de l’outil de dessin à
site d’empilement . . . . . . . . . . . . . . . 6-5 utiliser . . . . . . . . . . . . . . . . . . . . . 7-12
Transformation d'un contrôle en un enfant Changement d’outil en utilisant un
empilable. . . . . . . . . . . . . . . . . . . . . 6-5 turbobouton . . . . . . . . . . . . . . . . . 7-13
Contrôle de l'empilement des contrôles Utilisation des outils de dessin . . . . . . . 7-14
enfant . . . . . . . . . . . . . . . . . . . . . . . 6-5 Dessiner sur un graphique . . . . . . . . . . 7-17
Contrôle du désempilement des contrôles Création de graphiques défilables . . . . . 7-17
enfant . . . . . . . . . . . . . . . . . . . . . . . 6-6 Ajout d’un contrôle image . . . . . . . . . . 7-18
Contrôle de la réponse des contrôles enfant Chargement et enregistrement de fichiers
aux opérations glisser-empiler . . . . . . . . 6-7 graphiques . . . . . . . . . . . . . . . . . . . 7-20
Manipulation du texte dans les contrôles . . .6-7 Chargement d’une image depuis un
Définition de l’alignement du texte . . . . . 6-7 fichier. . . . . . . . . . . . . . . . . . . . . . 7-20
Ajout de barres de défilement en mode Enregistrement d’une image dans un
exécution . . . . . . . . . . . . . . . . . . . . . 6-8 fichier. . . . . . . . . . . . . . . . . . . . . . 7-20
Ajout de l’objet Clipboard . . . . . . . . . . . 6-9 Remplacement de l’image . . . . . . . . . . 7-21
Sélection de texte. . . . . . . . . . . . . . . . . 6-9 Utilisation du Presse-papiers avec les
graphiques . . . . . . . . . . . . . . . . . . . 7-22
Sélection de la totalité d’un texte . . . . . . . 6-10
Copier des graphiques dans le
Couper, copier et coller du texte . . . . . . . 6-10 Presse-papiers. . . . . . . . . . . . . . . . . 7-22
Effacement du texte sélectionné . . . . . . . . 6-11 Couper des graphiques dans le
Désactivation des éléments de menu . . . . 6-11 Presse-papiers. . . . . . . . . . . . . . . . . 7-23
Ajout d’un menu surgissant . . . . . . . . . . 6-12
iv
Coller des graphiques depuis le Chapitre 9
Presse-papiers . . . . . . . . . . . . . . . . 7-23
Techniques de dessin dans une Utilisation des paquets
application . . . . . . . . . . . . . . . . . . . . 7-24 et des composants 9-1
Répondre à la souris . . . . . . . . . . . . . . 7-24
Ajout d’un champ à un objet fiche . . . . 7-27
Pourquoi utiliser des paquets ? . . . . . . . . 9-2
Amélioration du dessin des lignes . . . . . 7-28 Les paquets et les DLL standard. . . . . . . . 9-2
Utilisation du multimédia . . . . . . . . . . . 7-30 Paquets d’exécution . . . . . . . . . . . . . . . 9-3
Ajout de séquences vidéo silencieuses à Utilisation des paquets dans une
une application . . . . . . . . . . . . . . . . . 7-30 application . . . . . . . . . . . . . . . . . . . . 9-3
Exemple d'ajout de séquences vidéo Paquets chargés dynamiquement . . . . . . . 9-4
silencieuses . . . . . . . . . . . . . . . . . . 7-31 Choix des paquets d’exécution à utiliser . . . 9-4
Ajout de séquences audio et/ou vidéo à Paquets personnalisés . . . . . . . . . . . . . . 9-5
une application . . . . . . . . . . . . . . . . . 7-32 Paquets de conception. . . . . . . . . . . . . . 9-6
Exemple d'ajout de séquences audio Installation de paquets de composants . . . . 9-6
et / ou vidéo . . . . . . . . . . . . . . . . . 7-34 Création et modification de paquets . . . . . 9-8
Création d’un paquet. . . . . . . . . . . . . . . 9-8
Chapitre 8 Modification d’un paquet existant . . . . . . . 9-9
Ecriture d’applications multithreads 8-1 Modification manuelle de fichiers source
Définition d’objets thread. . . . . . . . . . . . .8-2 de paquets . . . . . . . . . . . . . . . . . . . . 9-9
Initialisation du thread . . . . . . . . . . . . . 8-3 Présentation de la structure d’un paquet. . 9-10
Affectation d’une priorité par défaut . . . . 8-3 Nom de paquets . . . . . . . . . . . . . . . . 9-10
Libération des threads . . . . . . . . . . . . . 8-3 La clause Requires . . . . . . . . . . . . . . . 9-10
Ecriture de la fonction thread . . . . . . . . . 8-4 La clause Contains. . . . . . . . . . . . . . . 9-11
Utilisation du thread principal VCL . . . . . 8-4 Compilation de paquets . . . . . . . . . . . . 9-11
Utilisation de variables locales aux Directives de compilation propres aux
threads . . . . . . . . . . . . . . . . . . . . . . 8-5 paquets . . . . . . . . . . . . . . . . . . . . . 9-11
Vérification de l’arrêt par d’autres threads . . 8-6 Utilisation du compilateur et du lieur en
ligne de commande . . . . . . . . . . . . . 9-13
Ecriture du code de nettoyage . . . . . . . . 8-6
Fichiers paquets créés lors d’une
Coordination de threads . . . . . . . . . . . . .8-7 compilation réussie . . . . . . . . . . . . . 9-13
Eviter les accès simultanés . . . . . . . . . . . 8-7 Déploiement de paquets . . . . . . . . . . . . 9-14
Verrouillage d’objets. . . . . . . . . . . . . . . 8-7 Déploiement d’applications utilisant des
Utilisation de sections critiques . . . . . . . . 8-7 paquets . . . . . . . . . . . . . . . . . . . . . 9-14
Utilisation du synchronisateur à écriture Distribution de paquets à d’autres
exclusive et lecture multiple. . . . . . . . . 8-8 développeurs . . . . . . . . . . . . . . . . . . 9-14
Autres techniques de partage de la Fichiers de collection de paquet . . . . . . 9-14
mémoire . . . . . . . . . . . . . . . . . . . . . 8-9
Attente des autres threads . . . . . . . . . . . 8-9
Attente de la fin d’exécution d’un thread . 8-9
Chapitre 10
Attente de l’achèvement d’une tâche . . . 8-10 Création d’applications
Exécution d’objets thread . . . . . . . . . . . . 8-11 internationales 10-1
Redéfinition de la priorité par défaut . . . . 8-11
Internationalisation et localisation . . . . . . . 10-1
Démarrage et arrêt des threads . . . . . . . . 8-12
Internationalisation . . . . . . . . . . . . . . . 10-1
Utilisation des threads dans les applications Localisation . . . . . . . . . . . . . . . . . . . . 10-1
distribuées . . . . . . . . . . . . . . . . . . . . 8-12
Internationalisation des applications . . . . . 10-2
Utilisation des threads dans les serveurs
de messagerie . . . . . . . . . . . . . . . . . . 8-12 Codage de l’application . . . . . . . . . . . . 10-2
Utilisation des threads avec les objets Jeux de caractères . . . . . . . . . . . . . . . 10-2
distribués. . . . . . . . . . . . . . . . . . . . . 8-13 Jeux de caractères OEM et ANSI . . . . . . 10-2
Ecriture d'applications (fichiers .EXE) . . . 8-13 Jeux de caractères sur deux octets . . . . . 10-2
Ecriture de bibliothèques. . . . . . . . . . . 8-14 Caractères larges . . . . . . . . . . . . . . . . 10-3
Inclure des fonctionnalités
Débogage d’applications multithreads . . . . 8-15 bi-directionnelles dans les applications . 10-4
Propriété BiDiMode . . . . . . . . . . . . . . 10-6
v
Fonctionnalités spécifiques aux cibles Partie II
locales . . . . . . . . . . . . . . . . . . . . . 10-8
Conception de l’interface utilisateur . . . . . 10-8 Développement d’applications
Texte . . . . . . . . . . . . . . . . . . . . . . . 10-9
Images graphiques . . . . . . . . . . . . . . 10-9
de base de données
Formats et ordre de tri . . . . . . . . . . . . 10-9
Correspondances entre claviers . . . . . . .10-10 Chapitre 12
Isolement des ressources . . . . . . . . . . . 10-10 Conception d’applications de
Création de DLL de ressources . . . . . . . 10-10 bases de données 12-1
Utilisation des DLL de ressource . . . . . . 10-12
Basculement dynamique de DLL de Utilisation des bases de données . . . . . . . 12-2
ressource . . . . . . . . . . . . . . . . . . . . 10-13 Types de bases de données . . . . . . . . . . 12-2
Localisation des applications. . . . . . . . . 10-13 Bases de données locales . . . . . . . . . . . 12-3
Localisation des ressources . . . . . . . . . . 10-13 Serveurs de bases de données distants . . 12-3
Sécurité des bases de données . . . . . . . . 12-4
Chapitre 11 Transactions. . . . . . . . . . . . . . . . . . . . 12-5
Dictionnaire de données . . . . . . . . . . . . 12-5
Déploiement des applications 11-1 Intégrité référentielle, procédures stockées
Déploiement d’applications généralistes. . . 11-1 et déclencheurs. . . . . . . . . . . . . . . . . 12-7
Utilisation des programmes d’installation. . 11-2 Architecture des bases de données . . . . . . 12-7
Identification des fichiers de Anticipation de l’évolutivité. . . . . . . . . . 12-8
l’application . . . . . . . . . . . . . . . . . . 11-2 Applications de base de données à niveau
Les fichiers de l’application, par unique . . . . . . . . . . . . . . . . . . . . . 12-10
extension de fichier . . . . . . . . . . . . . 11-3 Applications de base de données à niveau
Fichiers paquet . . . . . . . . . . . . . . . . . 11-3 double . . . . . . . . . . . . . . . . . . . . . 12-10
Contrôles ActiveX . . . . . . . . . . . . . . . 11-3 Applications de base de données
Applications complémentaires . . . . . . . 11-4 multiniveaux . . . . . . . . . . . . . . . . . .12-11
Emplacement des DLL . . . . . . . . . . . . 11-4
Conception de l’interface utilisateur . . . . 12-13
Déploiement d’applications de base de Affichage d’un seul enregistrement . . . . 12-13
données. . . . . . . . . . . . . . . . . . . . . . 11-4 Affichage de plusieurs enregistrements. . 12-14
L’accès au moteur de bases de données. . . 11-4 Analyse des données . . . . . . . . . . . . . 12-15
Le moteur de bases de données Borland . 11-5
Sélection des données à afficher . . . . . . 12-15
Autres moteurs de bases de données . . . 11-5
Ecriture de rapports. . . . . . . . . . . . . . 12-18
SQL Links. . . . . . . . . . . . . . . . . . . . 11-5
MIDAS, services d’application distribuée Chapitre 13
multiniveau . . . . . . . . . . . . . . . . . . . 11-6
Déploiement d’applications Web . . . . . . . 11-7 Construction d’applications à
Programmer pour des environnements niveau unique et à niveau double 13-1
hôtes hétérogènes. . . . . . . . . . . . . . . . 11-8 Applications basées sur le BDE . . . . . . . . 13-2
Résolution d’écran et profondeurs de Architecture basée sur le BDE . . . . . . . . 13-2
couleur . . . . . . . . . . . . . . . . . . . . . . 11-8 Présentation des bases de données et des
Si vous n’utilisez pas de redimension- ensembles de données . . . . . . . . . . . 13-3
nement dynamique . . . . . . . . . . . . . 11-9 Utilisation des sessions . . . . . . . . . . . . 13-4
Si vous redimensionnez dynamiquement
les fiches et les contrôles . . . . . . . . . . 11-9 Connexion aux bases de données . . . . . . 13-5
Adaptation à des profondeurs de Utilisation des transactions . . . . . . . . . . 13-5
couleur variables. . . . . . . . . . . . . . .11-10 Contrôle explicite des transactions . . . . . 13-6
Fontes. . . . . . . . . . . . . . . . . . . . . . . 11-11 Utilisation d’un composant base de
données pour les transactions . . . . . . . 13-7
Versions de Windows . . . . . . . . . . . . . 11-11
Utilisation de la propriété TransIsolation . 13-8
Termes du contrat de licence logicielle . . 11-12 Utilisation du SQL direct. . . . . . . . . . . 13-9
DEPLOY.TXT. . . . . . . . . . . . . . . . . . 11-12 Utilisation des transactions locales . . . . 13-10
README.TXT . . . . . . . . . . . . . . . . . 11-12 Mise en mémoire cache des mises à jour .13-11
Contrat de licence . . . . . . . . . . . . . . . 11-12 Création et restructuration des tables de
Documentation de produits vendus par base de données . . . . . . . . . . . . . . . .13-11
un tiers . . . . . . . . . . . . . . . . . . . . . 11-12
vi
Applications basées sur ADO . . . . . . . . 13-12 Extension de l’interface du serveur
Architecture basée sur ADO . . . . . . . . . 13-12 d’applications. . . . . . . . . . . . . . . . . 14-19
Bases de données et ensembles de Ajout de rappels à l’interface du serveur
données ADO . . . . . . . . . . . . . . . .13-13 d’applications . . . . . . . . . . . . . . . . 14-20
Connexion aux bases de données ADO. . 13-13 Extension de l’interface du serveur
Accès aux données. . . . . . . . . . . . . . . 13-14 d’applications lors de l’utilisation de
MTS. . . . . . . . . . . . . . . . . . . . . . 14-20
Création et restructuration de tables de bases
de données ADO. . . . . . . . . . . . . . . 13-15 Création de l’application client . . . . . . . 14-21
Applications de base de données Connexion au serveur d’applications . . . 14-22
linéaires . . . . . . . . . . . . . . . . . . . . . 13-15 Spécification d’une connexion à l’aide
de DCOM . . . . . . . . . . . . . . . . . . 14-23
Création des ensembles de données . . . . 13-16
Spécification d’une connexion à l’aide
Création d’un nouvel ensemble de de sockets . . . . . . . . . . . . . . . . . . 14-23
données à l’aide de champs persistants.13-16
Spécification d’une connexion à l’aide
Création d’un ensemble de données à de HTTP . . . . . . . . . . . . . . . . . . . 14-24
l’aide de définitions de champ et
d’index. . . . . . . . . . . . . . . . . . . . .13-17 Spécification d’une connexion à l’aide
de OLEnterprise . . . . . . . . . . . . . . 14-25
Création d’un ensemble de données à
partir d’une table existante . . . . . . . .13-18 Spécification d’une connexion à l’aide
de CORBA. . . . . . . . . . . . . . . . . . 14-25
Chargement et enregistrement des Courtage de connexions . . . . . . . . . . 14-26
données. . . . . . . . . . . . . . . . . . . . . 13-19
Gestion des connexions serveur . . . . . . 14-26
Utilisation du modèle “briefcase”. . . . . . 13-20
Connexion au serveur. . . . . . . . . . . . 14-26
Passage à une application à niveau triple. 13-21 Fermeture ou changement de connexion
serveur . . . . . . . . . . . . . . . . . . . . 14-27
Chapitre 14 Appel des interfaces serveur . . . . . . . . 14-27
Création d’applications Gestion des transactions dans les
multiniveaux 14-1 applications multiniveaux . . . . . . . . . . 14-29
Gestion des relations maître / détail . . . . 14-30
Avantages du modèle de base de données
multiniveau . . . . . . . . . . . . . . . . . . . 14-2 Gestion des informations d’état dans les
modules de données distants . . . . . . . 14-30
Présentation de la technologie MIDAS . . . 14-3
Présentation d’une application multiniveau
Ecriture des applications MIDAS Web . . . 14-32
basée sur MIDAS. . . . . . . . . . . . . . . . 14-3 Distribution d’une application client en
Structure de l’application client . . . . . . . . 14-4 tant que contrôle ActiveX . . . . . . . . . 14-33
Création d’une fiche active pour
Structure du serveur d’applications . . . . . 14-5 l’application client . . . . . . . . . . . . . 14-34
Utilisation de MTS . . . . . . . . . . . . . . 14-6 Construction des applications Web avec
Regroupement des modules de données InternetExpress. . . . . . . . . . . . . . . . 14-34
distants . . . . . . . . . . . . . . . . . . . . 14-8
Construction d’une application
Utilisation de l’interface IAppServer. . . . 14-8 InternetExpress . . . . . . . . . . . . . . . 14-35
Sélection d’un protocole de connexion. . . . 14-9 Utilisation des bibliothèques javascript . 14-36
Utilisation de connexions DCOM . . . . .14-10 Droits d’accès au serveur d’applications
Utilisation de connexions Socket . . . . . .14-10 et à son lancement. . . . . . . . . . . . . 14-37
Utilisation de connexions Web . . . . . . .14-11 Utilisation d’un courtier XML . . . . . . . 14-38
Utilisation de OLEnterprise . . . . . . . . .14-12 Lecture des paquets de données XML . 14-38
Utilisation de connexions CORBA . . . . .14-12 Application des mises à jour à partir des
Construction d’une application paquets delta XML . . . . . . . . . . . . 14-39
multiniveau . . . . . . . . . . . . . . . . . . 14-12 Création des pages Web avec un
Création du serveur d’applications. . . . . 14-13 producteur de page MIDAS. . . . . . . . 14-40
Configuration du module de données Utilisation de l’éditeur de pages Web . . 14-41
distant . . . . . . . . . . . . . . . . . . . . . 14-15 Définition des propriétés des éléments
Configuration de TRemoteDataModule . .14-15 Web . . . . . . . . . . . . . . . . . . . . . . 14-42
Configuration de TMTSDataModule. . . .14-16 Personnalisation du modèle d’un
Configuration de TCorbaDataModule . . .14-17 producteur de page MIDAS . . . . . . . 14-43
Création d’un fournisseur de données
pour le serveur d’applications . . . . . . . 14-19
vii
Chapitre 15 Recherche de la connexion d’une base de
données . . . . . . . . . . . . . . . . . . . . . 16-9
Utilisation des composants Extraction d’informations sur une
fournisseur 15-1 session . . . . . . . . . . . . . . . . . . . . . 16-10
Manipulation des alias BDE. . . . . . . . . .16-11
Spécification de la source de données . . . . 15-1
Spécification de la visibilité des alias . . 16-11
Comment appliquer les modifications . . . . 15-2 Comment rendre des alias visibles aux
Contrôle des informations placées dans les autres sessions et applications. . . . . . 16-11
paquets de données . . . . . . . . . . . . . . 15-2 Comment déterminer les alias, les pilotes
Spécification des champs apparaissant et les paramètres connus . . . . . . . . . 16-11
dans les paquets de données . . . . . . . . 15-3 Création, modification et suppression
Initialisation des options contrôlant les des alias . . . . . . . . . . . . . . . . . . . 16-12
paquets de données . . . . . . . . . . . . . . 15-3 Déplacement parmi les composants base
Ajout d’informations personnalisées aux de données d’une session . . . . . . . . . 16-13
paquets de données . . . . . . . . . . . . . . 15-5 Spécification de l’emplacement des
Comment répondre aux demandes de répertoires Paradox . . . . . . . . . . . . . 16-14
données des clients. . . . . . . . . . . . . . . 15-5 Spécification de l’emplacement du
fichier de contrôle . . . . . . . . . . . . . 16-14
Comment répondre aux demandes de Spécification de l’emplacement des
mise à jour des clients. . . . . . . . . . . . . 15-6 fichiers temporaires . . . . . . . . . . . . 16-15
Modification des paquets delta avant la Manipulation de tables Paradox et dBase
mise à jour de la base de données . . . . . 15-7 protégées par mot de passe . . . . . . . . 16-15
Comment contrôler l’application des mises Utilisation de la méthode
à jour . . . . . . . . . . . . . . . . . . . . . . . 15-8 AddPassword . . . . . . . . . . . . . . . . 16-15
Filtrage des mises à jour . . . . . . . . . . . . 15-9 Utilisation des méthodes
Résolution des erreurs de mise à jour par RemovePassword et
le fournisseur . . . . . . . . . . . . . . . . . 15-10 RemoveAllPasswords . . . . . . . . . . . 16-16
Application des mises à jour à des Utilisation de la méthode GetPassword
ensembles de données représentant et de l’événement OnPassword . . . . . 16-16
plusieurs tables . . . . . . . . . . . . . . . . 15-10 Gestion de plusieurs sessions . . . . . . . . 16-17
Comment répondre aux événements Utilisation d’un composant session dans
générés par le client . . . . . . . . . . . . . 15-11 des modules de données . . . . . . . . . . 16-19
Gestion des contraintes du serveur. . . . . 15-11
Chapitre 17
Chapitre 16 Connexion aux bases de données 17-1
Gestion de sessions de bases Présentation des composants base de
de données 16-1 données persistants et temporaires . . . . . 17-1
Manipulation d’un composant session. . . . 16-2 Utilisation des composants base de
données temporaires . . . . . . . . . . . . . 17-2
Utilisation de la session par défaut. . . . . . 16-2
Création de composants base de données
Création de sessions supplémentaires . . . . 16-3 en mode conception . . . . . . . . . . . . . 17-3
Dénomination d’une session . . . . . . . . . . 16-4 Création de composants base de données
Activation d’une session . . . . . . . . . . . . 16-5 à l’exécution . . . . . . . . . . . . . . . . . . 17-3
Personnalisation du démarrage d’une Contrôle des connexions . . . . . . . . . . . . 17-4
session . . . . . . . . . . . . . . . . . . . . . . 16-6
Association d’un composant base de
Spécification du comportement par défaut données à une session . . . . . . . . . . . . 17-4
de connexion aux bases de données . . . . 16-6
Spécification d’un alias BDE . . . . . . . . . 17-5
Création, ouverture et fermeture des
connexions de bases de données . . . . . . 16-7 Définition des paramètres des alias BDE. . 17-6
Fermeture d’une connexion de base de Contrôle de la connexion au serveur . . . . 17-7
données . . . . . . . . . . . . . . . . . . . . 16-8 Connexion à un serveur de bases de
Fermeture de toutes les connexions de données . . . . . . . . . . . . . . . . . . . . . 17-7
base de données . . . . . . . . . . . . . . . 16-8 Considérations relatives à la connexion à
Abandon des connexions aux bases de un serveur distant. . . . . . . . . . . . . . . 17-8
données temporaires. . . . . . . . . . . . . . 16-9 Utilisation des protocoles réseau . . . . . . 17-8
Utilisation de ODBC. . . . . . . . . . . . . . 17-9
viii
Déconnexion d’un serveur de base de Utilisation de la méthode Lookup . . . . . 18-18
données. . . . . . . . . . . . . . . . . . . . . . 17-9 Affichage et édition d’ensembles de
Fermeture d’ensembles de données sans données en utilisant des filtres. . . . . . . 18-19
déconnexion du serveur . . . . . . . . . . . 17-9 Activation et désactivation des filtres . . . 18-19
Déplacement parmi les ensembles de Création de filtres . . . . . . . . . . . . . . . 18-19
données d’un composant base de Définition de la propriété Filter . . . . . . 18-20
données. . . . . . . . . . . . . . . . . . . . . 17-10
Ecriture d’un gestionnaire d’événement
Interactions entre les composants base de OnFilterRecord . . . . . . . . . . . . . . . . 18-21
données et les composants session . . . . 17-10 Permutation entre les gestionnaires
Utilisation de composants base de données d’événement filtre à l’exécution . . . . . 18-22
dans des modules de données. . . . . . . 17-11 Définition d’options de filtre . . . . . . . . 18-22
Exécution d’instructions SQL depuis un Navigation parmi les enregistrements
composant TDatabase . . . . . . . . . . . . 17-11 d’un ensemble de données filtré . . . . . 18-23
Exécution d’instructions SQL sans Modification des données. . . . . . . . . . . 18-24
ensemble de résultats . . . . . . . . . . . . 17-11 Modification d’enregistrements . . . . . . . 18-24
Exécution d’instructions SQL avec Ajout de nouveaux enregistrements . . . . 18-25
ensembles de résultats. . . . . . . . . . . . 17-12 Insertion d’enregistrements. . . . . . . . . 18-26
Exécution d’instructions SQL Ajout d’enregistrements. . . . . . . . . . . 18-26
paramétrées . . . . . . . . . . . . . . . . . . 17-13 Suppression d’enregistrements . . . . . . . 18-27
Validation des modifications . . . . . . . . 18-27
Chapitre 18 Annulation des modifications. . . . . . . . 18-27
Présentation des ensembles de Modification d’enregistrements entiers . . 18-28
données 18-1 Utilisation des événements des ensembles
de données . . . . . . . . . . . . . . . . . . . 18-29
Présentation de l’objet TDataSet . . . . . . . 18-2 Interruption d’une méthode. . . . . . . . . 18-30
Types d’ensembles de données . . . . . . . . 18-3 Utilisation de l’événement OnCalcFields . 18-30
Ouverture et fermeture des ensembles de Utilisation des ensembles de données
données. . . . . . . . . . . . . . . . . . . . . . 18-3 orientés BDE . . . . . . . . . . . . . . . . . . 18-31
Détermination et définition des états d’un Présentation de l’orientation BDE . . . . . 18-32
ensemble de données . . . . . . . . . . . . . 18-4 Gestion des connexions de base de
Désactivation d’un ensemble de données . . 18-6 données et de session. . . . . . . . . . . . 18-32
Visualisation d’un ensemble de données . . 18-7 Utilisation des propriétés DatabaseName
Activation de l’édition d’un ensemble de et SessionName. . . . . . . . . . . . . . . 18-33
données. . . . . . . . . . . . . . . . . . . . . . 18-8 Utilisation des propriétés de handle
Activation de l’insertion de nouveaux BDE . . . . . . . . . . . . . . . . . . . . . . 18-33
enregistrements . . . . . . . . . . . . . . . . . 18-8 Utilisation des mises à jour en mémoire
Activation de recherches indexées et cache . . . . . . . . . . . . . . . . . . . . . . 18-33
définition de portées. . . . . . . . . . . . . . 18-9 Mise en mémoire cache des BLOB . . . . 18-35
Champs calculés . . . . . . . . . . . . . . . . 18-10
Filtrage d’enregistrements . . . . . . . . . . 18-10 Chapitre 19
Mise à jour d’enregistrements . . . . . . . . 18-10 Manipulation des composants
Navigation dans les ensembles de champ 19-1
données. . . . . . . . . . . . . . . . . . . . . 18-10
Utilisation des méthodes First et Last . . . 18-11 Présentation des composants champ . . . . . 19-2
Utilisation des méthodes Next et Prior . . 18-12 Champs dynamiques . . . . . . . . . . . . . . 19-3
Utilisation de la méthode MoveBy . . . . . 18-12 Champs persistants . . . . . . . . . . . . . . . 19-4
Utilisation des propriétés Eof et Bof . . . . 18-13 Création de champs persistants . . . . . . . . 19-6
Eof . . . . . . . . . . . . . . . . . . . . . . . .18-13 Modification de l’ordre des champs
Bof . . . . . . . . . . . . . . . . . . . . . . . .18-14 persistants . . . . . . . . . . . . . . . . . . . . 19-7
Marquage d’enregistrements . . . . . . . . . 18-15 Définition de nouveaux champs
Recherche dans les ensembles de persistants . . . . . . . . . . . . . . . . . . . . 19-7
données. . . . . . . . . . . . . . . . . . . . . 18-17 Définition d’un champ de données . . . . . 19-9
Utilisation de la méthode Locate . . . . . . 18-17 Définition d’un champ calculé . . . . . . . 19-10
ix
Programmation d’un champ calculé . . . . 19-10 Utilisation de champs de référence . . . . 19-31
Définition d’un champ de référence . . . . 19-11 Affichage des champs de référence . . . 19-32
Définition d’un champ agrégat . . . . . . . 19-13 Accès aux données d’un champ de
Suppression de champs persistants. . . . . 19-14 référence . . . . . . . . . . . . . . . . . . . 19-32
Définition des événements et des
propriétés des champs persistants . . . . 19-14 Chapitre 20
Définition des propriétés d’affichage et Manipulation des tables 20-1
d’édition en mode conception . . . . . . . 19-15 Utilisation des composants table . . . . . . . 20-1
Définition des propriétés des composants
champ à l’exécution . . . . . . . . . . . . . 19-16 Configuration d’un composant table . . . . . 20-2
Création d’ensembles d’attributs pour les Spécification de l’emplacement d’une base
composants champ. . . . . . . . . . . . . . 19-17 de données . . . . . . . . . . . . . . . . . . . 20-2
Association des ensembles d’attributs aux Spécification d’un nom de table . . . . . . . 20-3
composants champ. . . . . . . . . . . . . . 19-17 Spécification du type des tables locales. . . 20-3
Suppression des associations d’ensembles Ouverture et fermeture d’une table . . . . . 20-4
d’attributs . . . . . . . . . . . . . . . . . . . 19-18 Contrôle des privilèges d’écriture / lecture
Contrôle ou dissimulation de la saisie d’une table . . . . . . . . . . . . . . . . . . . . 20-5
utilisateur . . . . . . . . . . . . . . . . . . . 19-18 Recherche d’enregistrements . . . . . . . . . . 20-5
Utilisation des formats par défaut pour Recherche d’enregistrements à partir des
les champs numériques, date et heure. . 19-19 champs indexés . . . . . . . . . . . . . . . . 20-6
Gestion des événements . . . . . . . . . . . 19-20 Exécution d’une recherche avec les
Manipulation des méthodes de champ méthodes Goto . . . . . . . . . . . . . . . . 20-7
lors de l’exécution . . . . . . . . . . . . . . 19-20 Exécution d’une recherche avec les
méthodes Find . . . . . . . . . . . . . . . . 20-8
Affichage, conversion et accès aux valeurs
des champs . . . . . . . . . . . . . . . . . . 19-21 Spécification de l’enregistrement en cours
après une recherche. . . . . . . . . . . . . . 20-8
Affichage de valeurs dans les contrôles
standard . . . . . . . . . . . . . . . . . . . . 19-21 Recherche sur des clés partielles . . . . . . . 20-8
Conversion des valeurs de champs . . . . 19-22 Recherche avec un index secondaire . . . . 20-9
Accès à des valeurs par la propriété Réitération ou extension d’une recherche . 20-9
d’ensemble de données par défaut . . . . 19-23 Tri d’enregistrements. . . . . . . . . . . . . . 20-10
Accès à des valeurs par la propriété Extraction d’une liste d’index disponibles
Fields d’un ensemble de données. . . . . 19-23 avec GetIndexNames . . . . . . . . . . . . 20-10
Accès à des valeurs par la méthode Spécification d’un index secondaire avec
FieldByName d’un ensemble de IndexName . . . . . . . . . . . . . . . . . . 20-10
données. . . . . . . . . . . . . . . . . . . . . 19-24 Spécification d’un fichier d’index
Vérification de la valeur en cours d’un dBASE . . . . . . . . . . . . . . . . . . . . 20-10
champ. . . . . . . . . . . . . . . . . . . . . . 19-25 Spécification d’un ordre de tri pour les
tables SQL . . . . . . . . . . . . . . . . . . .20-11
Définition de la valeur par défaut d’un Spécification de champs avec
champ. . . . . . . . . . . . . . . . . . . . . . 19-25 IndexFieldNames. . . . . . . . . . . . . . 20-11
Utilisation de contraintes . . . . . . . . . . . 19-25 Vérification de la liste de champs d’un
Création d’une contrainte personnalisée. . 19-25 index . . . . . . . . . . . . . . . . . . . . . . 20-12
Utilisation des contraintes de serveur . . . 19-26 Manipulation d’un sous-ensemble de
Utilisation des champs objet . . . . . . . . . 19-27 données . . . . . . . . . . . . . . . . . . . . . 20-12
Affichage des champs ADT et tableau . . 19-27 Présentation des différences entre les
Utilisation des champs ADT. . . . . . . . . 19-28 portées et les filtres . . . . . . . . . . . . . 20-12
Accès aux valeurs de champ ADT. . . . .19-28 Création et application d’une nouvelle
Utilisation des champs tableau . . . . . . . 19-29 portée . . . . . . . . . . . . . . . . . . . . . 20-13
Accès aux valeurs de champs tableau. . .19-30 Définition des valeurs de début de
Utilisation des champs ensemble de portée. . . . . . . . . . . . . . . . . . . . . 20-13
données. . . . . . . . . . . . . . . . . . . . . 19-30 Définition des valeurs de fin de portée . 20-14
Affichage des champs ensemble de Définition des valeurs de début et de
données . . . . . . . . . . . . . . . . . . . .19-31 fin de portée . . . . . . . . . . . . . . . . 20-15
Accès aux données d’un ensemble de Spécification d’une portée à partir de
données imbriqué . . . . . . . . . . . . . .19-31 clés partielles . . . . . . . . . . . . . . . . 20-16
x
Inclusion ou exclusion d’enregistrements Spécification d’une instruction SQL à
correspondant aux valeurs d’une l’exécution. . . . . . . . . . . . . . . . . . . . 21-7
portée . . . . . . . . . . . . . . . . . . . . .20-16 Définition directe de la propriété SQL. . . 21-8
Application d’une portée. . . . . . . . . . .20-16 Chargement de la propriété SQL depuis
Annulation d’une portée . . . . . . . . . . .20-17 un fichier . . . . . . . . . . . . . . . . . . . 21-8
Modification d’une portée . . . . . . . . . . 20-17 Chargement de la propriété SQL depuis
Modification du début de la portée . . . .20-17 un objet liste de chaînes . . . . . . . . . . 21-9
Modification de la fin de la portée . . . .20-18 Définition de paramètres . . . . . . . . . . . . 21-9
Suppression de tous les enregistrements Attribution de paramètres en phase de
d’une table . . . . . . . . . . . . . . . . . . . 20-18 conception. . . . . . . . . . . . . . . . . . . 21-10
Suppression d’une table. . . . . . . . . . . . 20-18 Affectation de paramètres en phase
Changement du nom d’une table. . . . . . 20-18 d’exécution . . . . . . . . . . . . . . . . . . .21-11
Utilisation d’une source de données pour
Création d’une table . . . . . . . . . . . . . . 20-19 lier les paramètres. . . . . . . . . . . . . . .21-11
Importation des données d’une autre Exécution d’une requête. . . . . . . . . . . . 21-13
table . . . . . . . . . . . . . . . . . . . . . . . 20-21 Exécution d’une requête pendant la
Utilisation de TBatchMove . . . . . . . . . . 20-22 conception. . . . . . . . . . . . . . . . . . . 21-13
Création d’un composant action Exécution d’une requête pendant
groupée. . . . . . . . . . . . . . . . . . . . . 20-22 l’exécution. . . . . . . . . . . . . . . . . . . 21-14
Spécification d’un mode d’action Exécution d’une requête renvoyant un
groupée. . . . . . . . . . . . . . . . . . . . . 20-23 ensemble de résultats . . . . . . . . . . . 21-14
Ajout . . . . . . . . . . . . . . . . . . . . . . .20-24 Exécution d’une requête sans ensemble
Mise à jour . . . . . . . . . . . . . . . . . . .20-24 de résultats . . . . . . . . . . . . . . . . . 21-15
Ajout et mise à jour. . . . . . . . . . . . . .20-24 Préparation d’une requête . . . . . . . . . . 21-15
Copie. . . . . . . . . . . . . . . . . . . . . . .20-24 Réinitialisation de la préparation d’une
Suppression . . . . . . . . . . . . . . . . . . .20-25 requête . . . . . . . . . . . . . . . . . . . . . 21-15
Etablissement d’une correspondance Création de requêtes hétérogènes . . . . . . 21-16
entre les types de données . . . . . . . . . 20-25
Exécution d’une action groupée. . . . . . . 20-26 Amélioration des performances d’une
Gestion des erreurs relatives aux actions requête . . . . . . . . . . . . . . . . . . . . . 21-17
groupées . . . . . . . . . . . . . . . . . . . . 20-26 Désactivation des curseurs
bidirectionnels . . . . . . . . . . . . . . . . 21-17
Synchronisation de tables liées à la même
table . . . . . . . . . . . . . . . . . . . . . . . 20-27 Manipulation des ensembles de résultats . 21-17
Création de fiches maître-détail . . . . . . . 20-27 Activation de l’édition d’un ensemble de
résultats . . . . . . . . . . . . . . . . . . . . 21-18
Construction d’une fiche maître-détail Utilisation de SQL local avec les
exemple . . . . . . . . . . . . . . . . . . . . 20-28 ensembles de résultats modifiables . . . 21-18
Utilisation des tables imbriquées . . . . . . 20-29 Restrictions relatives aux requêtes
Configuration d’un composant table modifiables . . . . . . . . . . . . . . . . . 21-18
imbriquée . . . . . . . . . . . . . . . . . . . 20-29 Utilisation de SQL sur serveur distant
avec les ensembles de résultats
Chapitre 21 modifiables . . . . . . . . . . . . . . . . . . 21-19
Manipulation des requêtes 21-1 Restrictions sur la mise à jour d’un
ensemble de résultats modifiable. . . . . 21-19
Pour une utilisation efficace des requêtes. . 21-1 Mise à jour d’un ensemble de résultats
Informations pour les développeurs en lecture seulement . . . . . . . . . . . . 21-19
d’applications de bureau . . . . . . . . . . . 21-2
Informations pour les développeurs Chapitre 22
d’applications sur serveur . . . . . . . . . . 21-3
Bases de données accessibles par un Manipulation des procédures
composant requête . . . . . . . . . . . . . . . 21-4 stockées 22-1
Utilisation d’un composant requête . . . . . 21-4 Quand utiliser les procédures stockées ?. . . 22-2
Spécification de l’instruction SQL à Utilisation de procédures stockées . . . . . . 22-3
exécuter. . . . . . . . . . . . . . . . . . . . . . 21-6 Création d’un composant procédure
Spécification de la propriété SQL en phase stockée . . . . . . . . . . . . . . . . . . . . . . 22-4
de conception . . . . . . . . . . . . . . . . . . 21-7
xi
Création d’une procédure stockée . . . . . . 22-5 Activation et désactivation d’une
Préparation et exécution d’une procédure connexion . . . . . . . . . . . . . . . . . . . 23-5
stockée . . . . . . . . . . . . . . . . . . . . . . 22-5 Comment déterminer ce que fait un
Utilisation de procédures stockées qui composant connexion ? . . . . . . . . . . . 23-5
renvoient des ensembles de résultats . . . 22-6 Optimisation d’une connexion . . . . . . . . 23-6
Extraction d’un ensemble de résultat Spécification des attributs d’une
avec un composant TQuery . . . . . . . . 22-6 connexion . . . . . . . . . . . . . . . . . . . 23-6
Extraction d’un ensemble de résultat Contrôle des dépassements de délais . . . 23-7
avec un composant TStoredProc . . . . . 22-7 Contrôle de la boîte de dialogue
Utilisation de procédures stockées qui d’identification . . . . . . . . . . . . . . . . 23-8
renvoient des données à l’aide de Enumération des tables et procédures
paramètres . . . . . . . . . . . . . . . . . . . . 22-8 stockées . . . . . . . . . . . . . . . . . . . . . 23-9
Extraction de valeurs individuelles avec Accès aux ensembles de données d’une
un composant TQuery . . . . . . . . . . . 22-8 connexion . . . . . . . . . . . . . . . . . . . 23-9
Extraction de valeurs individuelles avec Accès aux commandes d’une connexion 23-10
un composant TStoredProc . . . . . . . . 22-9 Enumération des tables disponibles . . . 23-10
Utilisation de procédures stockées pour Enumération des procédures stockées
manipuler les données . . . . . . . . . . . . 22-9 disponibles . . . . . . . . . . . . . . . . . 23-11
Exécution d’une procédure stockée Utilisation des transactions de connexion .23-11
d’action avec un composant TQuery . .22-10 Utilisation des méthodes de transaction. 23-12
Exécution d’une procédure stockée Utilisation des événements de
d’action avec un composant transaction . . . . . . . . . . . . . . . . . . 23-12
TStoredProc . . . . . . . . . . . . . . . . . .22-10 Utilisation des ensembles de données
Présentation des paramètres des ADO . . . . . . . . . . . . . . . . . . . . . . . 23-12
procédures stockées . . . . . . . . . . . . . 22-11 Caractéristiques communes à tous les
Utilisation des paramètres d’entrée. . . . . 22-12 composants ensemble de données
Utilisation des paramètres de sortie . . . . 22-13 ADO . . . . . . . . . . . . . . . . . . . . . . 23-13
Utilisation des paramètres Modification des données . . . . . . . . . 23-13
d’entrée / sortie . . . . . . . . . . . . . . . . 22-13 Déplacement dans un ensemble de
Utilisation du paramètre résultat . . . . . . 22-14 données . . . . . . . . . . . . . . . . . . . 23-13
Accès aux paramètres en mode Utilisation des contrôles orientés
conception . . . . . . . . . . . . . . . . . . . 22-14 données . . . . . . . . . . . . . . . . . . . 23-14
Définition des informations sur les Connexion à un stockage de données en
paramètres à la conception. . . . . . . . . 22-15 utilisant des composants ensemble de
Création de paramètres en mode données ADO. . . . . . . . . . . . . . . . 23-14
exécution . . . . . . . . . . . . . . . . . . . . 22-16 Utilisation des ensembles
d’enregistrements. . . . . . . . . . . . . . 23-15
Liaison de paramètres. . . . . . . . . . . . . 22-17
Utilisation des mises à jour groupées . . 23-16
Visualisation des informations sur les Lecture et enregistrement des données
paramètres à la conception . . . . . . . . . 22-18 dans des fichiers . . . . . . . . . . . . . . 23-18
Manipulation des procédures stockées Utilisation de paramètres dans des
surchargées Oracle . . . . . . . . . . . . . . 22-19 commandes . . . . . . . . . . . . . . . . . 23-19
Utilisation de TADODataSet . . . . . . . . 23-20
Chapitre 23 Utilisation d’une commande pour
obtenir un ensemble de données . . . . 23-21
Utilisation des composants ADO 23-1 Utilisation de TADOTable . . . . . . . . . . 23-21
Présentation des composants ADO. . . . . . 23-1 Spécification de la table à utiliser. . . . . 23-22
Connexion à des stockages de données Utilisation de TADOQuery . . . . . . . . . 23-22
ADO. . . . . . . . . . . . . . . . . . . . . . . . 23-3 Spécification des instructions SQL . . . . 23-23
Connexion à un stockage de données avec Exécution d’instructions SQL . . . . . . . 23-23
TADOConnection. . . . . . . . . . . . . . . . 23-3 Utilisation de TADOStoredProc . . . . . . 23-24
Utilisation de TADOConnection ou de la Spécification de la procédure stockée . . 23-25
propriété ConnectionString d’un Exécution d’une procédure stockée. . . . 23-26
ensemble de données . . . . . . . . . . . . 23-3 Utilisation des paramètres de procédures
Spécification de la connexion . . . . . . . . 23-4 stockées . . . . . . . . . . . . . . . . . . . 23-26
Accès à l’objet connexion . . . . . . . . . . 23-4
xii
Exécution de commandes . . . . . . . . . . 23-28 Transmission de paramètres au serveur
Spécification de la commande . . . . . . .23-29 d’applications. . . . . . . . . . . . . . . . . 24-18
Utilisation de la méthode Execute . . . . .23-30 Envoi de paramètres de requête ou de
Annulation de commandes . . . . . . . . .23-30 procédure stockée . . . . . . . . . . . . . 24-19
Utilisation des ensembles de résultats Limitation des enregistrements avec
des commandes . . . . . . . . . . . . . . .23-30 des paramètres . . . . . . . . . . . . . . . 24-19
Gestion des paramètres de commande . .23-31 Redéfinition de l’ensemble de données
sur le serveur d’applications . . . . . . . 24-20
Chapitre 24 Extraction des données depuis un serveur
d’applications. . . . . . . . . . . . . . . . . 24-20
Création et utilisation d’un Gestion des contraintes. . . . . . . . . . . . 24-22
ensemble de données client 24-1 Gestion des contraintes depuis le
serveur . . . . . . . . . . . . . . . . . . . . 24-22
Manipulation des données avec un
Ajout de contraintes personnalisées . . . 24-23
ensemble de données client . . . . . . . . . 24-2
Mise à jour des enregistrements . . . . . . 24-24
Navigation parmi les données des
Application des mises à jour . . . . . . . 24-24
ensembles de données client. . . . . . . . . 24-2
Régularisation des erreurs de mise à
Limitation des enregistrements affichés . . . 24-3 jour . . . . . . . . . . . . . . . . . . . . . . 24-26
Représentation des relations Rafraîchissement des enregistrements . . . 24-27
maître / détail . . . . . . . . . . . . . . . . . . 24-3
Communication avec des fournisseurs à
Définition de contraintes pour les valeurs l’aide d’événements personnalisés . . . . 24-28
des données . . . . . . . . . . . . . . . . . . 24-4
Comment déclarer des données en lecture Utilisation d’un ensemble de données
seulement . . . . . . . . . . . . . . . . . . . . 24-5 client avec des données de fichier
Edition des données . . . . . . . . . . . . . . . 24-5 linéaire. . . . . . . . . . . . . . . . . . . . . . 24-28
Annulation des modifications . . . . . . . . 24-6 Création d’un nouvel ensemble de
Enregistrement des modifications . . . . . 24-6 données . . . . . . . . . . . . . . . . . . . . 24-29
Tri et indexation . . . . . . . . . . . . . . . . . 24-7 Chargement des données depuis un
fichier ou un flux . . . . . . . . . . . . . . 24-29
Ajout d’un nouvel index . . . . . . . . . . . 24-7
Suppression et permutation d’index . . . . 24-8 Fusion des modifications dans les
données . . . . . . . . . . . . . . . . . . . . 24-30
Utilisation des index pour regrouper les
données . . . . . . . . . . . . . . . . . . . . 24-9 Sauvegarde des données dans un fichier
Indexation à la volée . . . . . . . . . . . . .24-10 ou un flux. . . . . . . . . . . . . . . . . . . 24-30
Représentation des valeurs calculées. . . . 24-10
Utilisation de champs calculés de façon
Chapitre 25
interne dans les ensembles de données Manipulation des mises à jour
client . . . . . . . . . . . . . . . . . . . . . .24-10
Utilisation des agrégats maintenus . . . . . 24-11
en mémoire cache 25-1
Spécification d’agrégats. . . . . . . . . . . .24-11 Quand utiliser les mises à jour en mémoire
Agrégats de groupes d’enregistrements. .24-13 cache ?. . . . . . . . . . . . . . . . . . . . . . . 25-1
Obtention de valeurs d’agrégat . . . . . . .24-13 Utilisation des mises à jour en mémoire
Ajout d’informations d’application aux cache. . . . . . . . . . . . . . . . . . . . . . . . 25-2
données. . . . . . . . . . . . . . . . . . . . . 24-14 Activation et désactivation des mises à
Copie de données d’un autre ensemble de jour en mémoire cache . . . . . . . . . . . . 25-3
données. . . . . . . . . . . . . . . . . . . . . 24-14 Extraction d’enregistrements . . . . . . . . . 25-4
Affectation directe des données . . . . . . . 24-15 Application des mises à jour en mémoire
Clonage d’un curseur d’ensemble de cache . . . . . . . . . . . . . . . . . . . . . . . 25-5
données client. . . . . . . . . . . . . . . . . 24-16 Utilisation de la méthode d’un composant
Utilisation d’un ensemble de données base de données . . . . . . . . . . . . . . . 25-6
client avec un fournisseur de données. . 24-16 Utilisation des méthodes d’un composant
ensemble de données . . . . . . . . . . . . 25-7
Spécification d’un fournisseur de
données. . . . . . . . . . . . . . . . . . . . . 24-17 Application des mises à jour à des tables
maître / détail. . . . . . . . . . . . . . . . . 25-8
Obtention de paramètres du serveur Annulation des mises à jour en mémoire
d’applications . . . . . . . . . . . . . . . . . 24-17 cache en suspens . . . . . . . . . . . . . . . 25-9
xiii
Annulation des mises à jour en suspens Manipulation du texte d’un message
et désactivation des mises à jour d’erreur . . . . . . . . . . . . . . . . . . . . 25-30
suivantes. . . . . . . . . . . . . . . . . . . . 25-9 Accès aux propriétés OldValue,
Annulation des mises à jour en mémoire NewValue et CurValue d’un champ. . . 25-31
cache en suspens. . . . . . . . . . . . . . . 25-9
Annulation des mises à jour apportées à Chapitre 26
l’enregistrement en cours . . . . . . . . .25-10
Récupération d’enregistrements en Utilisation de contrôles de
mémoire cache . . . . . . . . . . . . . . . . 25-10 données 26-1
Spécification des enregistrements visibles
en mémoire cache . . . . . . . . . . . . . . 25-11 Fonctionnalités communes des contrôles
Vérification de l’état de la mise à jour. . . 25-12 de données . . . . . . . . . . . . . . . . . . . . 26-1
Association d’un contrôle de données à
Utilisation d’objets mise à jour pour un ensemble de données. . . . . . . . . . . 26-3
mettre à jour un ensemble de données . 25-13 Edition et mise à jour des données . . . . . 26-3
Spécification de la propriété UpdateObject Activation de l’édition des contrôles lors
d’un ensemble de données . . . . . . . . . 25-13 d’une saisie utilisateur . . . . . . . . . . . 26-3
Utilisation d’un seul objet mise à jour . .25-14 Edition des données affichées dans un
Utilisation de plusieurs objets mise à contrôle. . . . . . . . . . . . . . . . . . . . . 26-3
jour . . . . . . . . . . . . . . . . . . . . . . .25-14 Activation et désactivation de l’affichage
Création d’instructions SQL pour les des données . . . . . . . . . . . . . . . . . . 26-5
composants mise à jour. . . . . . . . . . . 25-15 Rafraîchissement de l’affichage des
Création d’instructions SQL lors de la données . . . . . . . . . . . . . . . . . . . . . 26-5
conception. . . . . . . . . . . . . . . . . . .25-16 Activation des événements souris, clavier
Substitution des paramètres dans les et timer . . . . . . . . . . . . . . . . . . . . . 26-6
instructions SQL de mise à jour . . . . .25-17
Elaboration des instructions SQL de Utilisation des sources de données . . . . . . 26-6
mise à jour . . . . . . . . . . . . . . . . . .25-18 Utilisation des propriétés de TDataSource . 26-6
Utilisation de la propriété Query d’un Propriété DataSet. . . . . . . . . . . . . . . . 26-7
composant mise à jour . . . . . . . . . . .25-19 Propriété Name. . . . . . . . . . . . . . . . . 26-7
Utilisation des propriétés DeleteSQL, Propriété Enabled . . . . . . . . . . . . . . . 26-7
InsertSQL et ModifySQL . . . . . . . . . .25-20 Propriété AutoEdit. . . . . . . . . . . . . . . 26-8
Exécution des instructions de mise à Utilisation des événements de
jour . . . . . . . . . . . . . . . . . . . . . . . 25-21 TDataSource . . . . . . . . . . . . . . . . . . 26-8
Appel de la méthode Apply . . . . . . . .25-21 Evénement OnDataChange . . . . . . . . . 26-8
Appel de la méthode SetParams . . . . . .25-22 Evénement OnUpdateData. . . . . . . . . . 26-8
Appel de la méthode ExecSQL . . . . . . .25-23 Evénement OnStateChange . . . . . . . . . 26-8
Utilisation de composants ensemble de Contrôles représentant un champ unique . . 26-9
données pour mettre à jour un Affichage de données en tant que libellés . 26-9
ensemble de données . . . . . . . . . . . . 25-24 Affichage et édition de champs dans une
Mise à jour d’un ensemble de résultat en boîte de saisie . . . . . . . . . . . . . . . . 26-10
lecture seule . . . . . . . . . . . . . . . . . . 25-25 Affichage et édition de texte dans un
Contrôle du processus de mise à jour . . . 25-25 contrôle mémo . . . . . . . . . . . . . . . . 26-10
Détermination de la nécessité de Affichage et édition dans un contrôle
contrôler le processus de mise à jour . . 25-26 mémo de texte formaté . . . . . . . . . . .26-11
Création d’un gestionnaire d’événement Affichage et édition de champs
OnUpdateRecord . . . . . . . . . . . . . . . 25-26 graphiques dans un contrôle image . . . 26-12
Gestion des erreurs de mise à jour en Affichage de données dans des boîtes
mémoire cache . . . . . . . . . . . . . . . . 25-28 liste et des boîtes à options . . . . . . . . 26-12
Référencement de l’ensemble de données Affichage et édition de données dans
à mettre à jour . . . . . . . . . . . . . . . . 25-28 une boîte liste. . . . . . . . . . . . . . . . 26-13
Indication du type de mise à jour ayant Affichage et édition de données dans
généré l’erreur . . . . . . . . . . . . . . . . 25-28 une boîte à options . . . . . . . . . . . . 26-13
Spécification de l’action à entreprendre . . 25-29 Affichage dans une boîte liste de
référence et une boîte à options de
référence. . . . . . . . . . . . . . . . . . . . 26-14
xiv
Spécification d’une liste basée sur un Chapitre 27
champ de référence . . . . . . . . . . . . .26-14
Propriétés des boîtes liste et des boîtes à Utilisation de composants d’aide
options de référence. . . . . . . . . . . . .26-15 à la décision 27-1
Recherche incrémentale dans les valeurs
d’une liste d’éléments. . . . . . . . . . . .26-16 Présentation . . . . . . . . . . . . . . . . . . . . 27-1
Manipulation de champs booléens avec Présentation des références croisées . . . . . 27-2
des cases à cocher . . . . . . . . . . . . . . 26-16 Références croisées à une dimension . . . . 27-3
Limitation de valeurs de champ avec des Références croisées à plusieurs dimensions 27-3
boutons radio . . . . . . . . . . . . . . . . . 26-17 Instructions relatives à l’utilisation de
Visualisation et édition des données avec composants d’aide à la décision . . . . . . . 27-3
un contrôle TDBGrid . . . . . . . . . . . . 26-18 Utilisation d’ensembles de données avec
Utilisation d’un contrôle grille à son état les composants d’aide à la décision. . . . . 27-5
par défaut . . . . . . . . . . . . . . . . . . . 26-19 Création d’ensembles de données de
Création d’une grille personnalisée. . . . . 26-20 décision avec TQuery ou TTable . . . . . . 27-6
Présentation des colonnes persistantes . .26-20 Création d’ensembles de données de
Détermination de la source d’une décision avec l’éditeur de requête de
propriété de colonne à l’exécution . . . .26-21 décision . . . . . . . . . . . . . . . . . . . . . 27-6
Création de colonnes persistantes . . . . .26-22 Utilisation de l’éditeur de requête de
Suppression de colonnes persistantes . . .26-23 décision . . . . . . . . . . . . . . . . . . . . 27-7
Modification de l’ordre des colonnes Propriétés d’une requête de décision . . . . 27-7
persistantes . . . . . . . . . . . . . . . . . .26-23
Utilisation des cubes de décision . . . . . . . 27-8
Définition d’une colonne de liste de
référence . . . . . . . . . . . . . . . . . . . .26-23 Propriétés et événements des cubes de
Définition d’une colonne de liste de décision . . . . . . . . . . . . . . . . . . . . . 27-8
choix . . . . . . . . . . . . . . . . . . . . . .26-23 Utilisation de l’éditeur de cube de
Insertion d’un bouton dans une décision . . . . . . . . . . . . . . . . . . . . . 27-8
colonne. . . . . . . . . . . . . . . . . . . . .26-24 Visualisation et modification des
Définition des propriétés de colonne en paramètres de dimensions . . . . . . . . . 27-9
mode conception. . . . . . . . . . . . . . .26-24 Définition du maximum de dimensions
Restauration des valeurs par défaut et de récapitulations . . . . . . . . . . . . . 27-9
d’une colonne . . . . . . . . . . . . . . . .26-25 Visualisation et modification des options
Affichage des champs ADT et tableau . . 26-25 de conception . . . . . . . . . . . . . . . . 27-10
Définition des options de la grille . . . . . 26-27 Utilisation de sources de décision. . . . . . 27-10
Saisie de modifications dans la grille . . . 26-28 Propriétés et événements . . . . . . . . . . 27-10
Changement de l’ordre des colonnes à la Utilisation de pivots de décision . . . . . . 27-11
conception . . . . . . . . . . . . . . . . . . . 26-29 Propriétés des pivots de décision . . . . . .27-11
Changement de l’ordre des colonnes à Création et utilisation de grilles de
l’exécution . . . . . . . . . . . . . . . . . . . 26-29 décision . . . . . . . . . . . . . . . . . . . . . 27-12
Contrôle du dessin de la grille . . . . . . .26-29 Création de grilles de décision . . . . . . . 27-12
Comment répondre aux actions de Utilisation de grilles de décision . . . . . . 27-12
l’utilisateur à l’exécution . . . . . . . . . . 26-30 Ouverture et fermeture des champs
Création d’une grille contenant d’autres d’une grille de décision. . . . . . . . . . 27-12
contrôles orientés données . . . . . . . . . 26-31 Réorganisation des lignes et des colonnes
Navigation et manipulation d’enregis- d’une grille de décision. . . . . . . . . . 27-13
trements . . . . . . . . . . . . . . . . . . . . 26-32 Perforation pour voir les détails dans les
Choix des boutons visibles. . . . . . . . . . 26-33 grilles de décision . . . . . . . . . . . . . 27-13
Affichage et dissimulation des boutons Limite des dimensions à sélectionner
en mode conception. . . . . . . . . . . . .26-34 dans les grilles de décision. . . . . . . . 27-13
Affichage et dissimulation des boutons Propriétés des grilles de décision . . . . . 27-14
à l’exécution . . . . . . . . . . . . . . . . .26-34 Création et utilisation de graphes de
Affichage de panneaux d’information . . . 26-35 décision . . . . . . . . . . . . . . . . . . . . . 27-15
Utilisation d’un navigateur pour Création de graphes de décision . . . . . . 27-15
plusieurs ensembles de données . . . . . 26-35 Utilisation de graphes de décision. . . . . 27-15
xv
Affichage du graphe de décision . . . . . . 27-17 Déploiement d’applications CORBA . . . . 28-18
Personnalisation du graphe de décision. . 27-17 Configuration de Smart Agents . . . . . . 28-19
Définition des modèles de graphe de Démarrage du Smart Agent . . . . . . . . 28-19
décision par défaut . . . . . . . . . . . . .27-18 Configuration de domaines ORB . . . . . 28-20
Personnalisation des séries d’un graphe Connexion de Smart Agents avec
de décision . . . . . . . . . . . . . . . . . .27-19 d’autres réseaux locaux . . . . . . . . . . 28-21
Utilisation des composants d’aide à la
décision à l’exécution . . . . . . . . . . . . 27-20 Chapitre 29
Pivots de décision à l’exécution . . . . . . . 27-20 Création d’applications serveur
Grilles de décision à l’exécution . . . . . . 27-21
Graphes de décision à l’exécution . . . . . 27-21 pour Internet 29-1
Considérations relatives au contrôle de la Terminologie et standard . . . . . . . . . . . . 29-1
mémoire . . . . . . . . . . . . . . . . . . . . 27-21 Composition d’un URL
Définition du maximum de dimensions, (Uniform Resource Locator) . . . . . . . . . 29-2
de champs récapitulatifs, et de cellules . 27-22 URI et URL . . . . . . . . . . . . . . . . . . . 29-2
Définition de l’état des dimensions. . . . . 27-22 En-tête de message de requête HTTP. . . . 29-3
Utilisation de dimensions paginées. . . . . 27-23 Activité d’un serveur HTTP . . . . . . . . . . 29-3
Composition des requêtes client . . . . . . . 29-3
Partie III Traitement des requêtes client par le
Ecriture d’applications distribuées serveur. . . . . . . . . . . . . . . . . . . . . . 29-4
Réponses aux requêtes client . . . . . . . . . 29-4
Applications serveur Web. . . . . . . . . . . . 29-5
Chapitre 28 Types d’applications serveur Web . . . . . . 29-5
Ecriture d’applications CORBA 28-1 ISAPI et NSAPI . . . . . . . . . . . . . . . . 29-5
Vue générale d’une application CORBA. . 28-2 CGI autonome . . . . . . . . . . . . . . . . . 29-6
Stubs et squelettes . . . . . . . . . . . . . . . . 28-3 Win-CGI autonome . . . . . . . . . . . . . . 29-6
Utilisation de Smart Agents . . . . . . . . . . 28-3 Création d’applications serveur Web . . . . 29-6
Activation d’applications serveur . . . . . . . 28-4 Le module Web . . . . . . . . . . . . . . . . . 29-6
Liaison dynamique d’appels d’interfaces . . 28-4 L’objet application Web . . . . . . . . . . . . 29-7
Ecriture de serveurs CORBA . . . . . . . . . 28-5 Structure d’une application serveur Web . . 29-8
Utilisation des experts CORBA . . . . . . . . 28-5 Le répartiteur Web . . . . . . . . . . . . . . . . 29-9
Définition d’interfaces d’objets . . . . . . . . 28-6 Ajout d’actions au répartiteur . . . . . . . . 29-9
Code généré automatiquement . . . . . . . . 28-8 Répartition des messages de requête . . . . 29-9
Recensement d’interfaces serveur . . . . . . . 28-9 Eléments d’action . . . . . . . . . . . . . . . . 29-10
Recensement d’interfaces avec le Choix du déclenchement des éléments
référentiel d’interfaces. . . . . . . . . . . . 28-9 d’action . . . . . . . . . . . . . . . . . . . . .29-11
Recensement d’interfaces avec l’Object URL de destination . . . . . . . . . . . . . 29-11
Activation Daemon . . . . . . . . . . . . .28-10 Type de méthode de requête . . . . . . . 29-11
Ecriture de clients CORBA . . . . . . . . . . 28-13 Activation et désactivation des éléments
Utilisation des stubs . . . . . . . . . . . . . . 28-13 d’action. . . . . . . . . . . . . . . . . . . . 29-11
Utilisation de l’interface d’appel Choix d’un élément d’action par défaut 29-12
dynamique. . . . . . . . . . . . . . . . . . . 28-14 Réponse aux messages de requête avec
Obtention de l’interface. . . . . . . . . . . .28-14 des éléments d’action. . . . . . . . . . . . 29-12
Appel d’interfaces avec DII . . . . . . . . .28-15 Envoi de la réponse . . . . . . . . . . . . . 29-13
Personnalisation d’applications CORBA. . 28-16 Utilisation de plusieurs éléments
d’action. . . . . . . . . . . . . . . . . . . . 29-13
Affichage d’objets dans l’interface
utilisateur . . . . . . . . . . . . . . . . . . . 28-17 Accès aux informations de requêtes
Présentation et dissimulation d’objets client . . . . . . . . . . . . . . . . . . . . . . . 29-14
CORBA. . . . . . . . . . . . . . . . . . . . . 28-17 Propriétés contenant des informations
Transmission d’informations client à des d’en-tête de requête . . . . . . . . . . . . . 29-14
objets serveur . . . . . . . . . . . . . . . . . 28-17 Propriétés identifiant la destination . . . 29-14
Propriétés décrivant le client Web . . . . 29-14
xvi
Propriétés identifiant le but de la Chapitre 30
requête . . . . . . . . . . . . . . . . . . . . .29-15
Propriétés décrivant la réponse attendue .29-15 Utilisation des sockets 30-1
Propriétés décrivant le contenu. . . . . . .29-15 Implémentation des services . . . . . . . . . . 30-1
Contenu d’un message de requête HTTP. 29-16 Description des protocoles de services . . . 30-2
Création de messages de réponse HTTP . 29-16 Communication avec les applications . . . 30-2
Informations d’en-tête de réponse . . . . . 29-16 Services et ports . . . . . . . . . . . . . . . . . 30-2
Indication du statut de la réponse . . . . .29-16 Types de connexions par socket . . . . . . . . 30-2
Indication d’attente d’une action du Connexions client . . . . . . . . . . . . . . . . 30-3
client . . . . . . . . . . . . . . . . . . . . . .29-17 Connexions d’écoute . . . . . . . . . . . . . . 30-3
Description de l’application serveur . . . .29-17 Connexions serveur . . . . . . . . . . . . . . . 30-3
Description du contenu . . . . . . . . . . .29-17
Description des sockets . . . . . . . . . . . . . 30-3
Définition du contenu de la réponse. . . . 29-17
Description des hôtes. . . . . . . . . . . . . . 30-4
Envoi de la réponse . . . . . . . . . . . . . . 29-18
Choix entre le nom de l’hôte et son
Génération du contenu des messages de adresse IP . . . . . . . . . . . . . . . . . . . 30-4
réponse . . . . . . . . . . . . . . . . . . . . . 29-18 Utilisation des ports . . . . . . . . . . . . . . 30-5
Utilisation du composant générateur de Utilisation des composants socket. . . . . . . 30-5
page. . . . . . . . . . . . . . . . . . . . . . . 29-19
Utilisation de sockets client . . . . . . . . . . 30-6
Modèles HTML . . . . . . . . . . . . . . . .29-19
Désignation du serveur souhaité . . . . . . 30-6
Choix du modèle HTML. . . . . . . . . . .29-20
Formation de la connexion. . . . . . . . . . 30-6
Conversion des balises HTML
transparentes . . . . . . . . . . . . . . . . .29-20 Obtention d’informations sur la
connexion . . . . . . . . . . . . . . . . . . . 30-6
Utilisation du générateur de page
depuis un élément d’action . . . . . . . .29-21 Fermeture de la connexion. . . . . . . . . . 30-7
Chaînage de générateurs de page . . . . .29-21 Utilisation de sockets serveur. . . . . . . . . 30-7
Désignation du port . . . . . . . . . . . . . . 30-7
Utilisation des bases de données dans les
Ecoute des requêtes client . . . . . . . . . . 30-7
réponses . . . . . . . . . . . . . . . . . . . . 29-23
Connexion aux clients. . . . . . . . . . . . . 30-7
Ajout d’une session au module Web. . . . 29-23 Obtenir des informations sur les
Représentation HTML d’une base de connexions. . . . . . . . . . . . . . . . . . . 30-8
données. . . . . . . . . . . . . . . . . . . . . 29-24 Fermeture des connexions serveur . . . . . 30-8
Utilisation des générateurs de page
ensemble de données . . . . . . . . . . . .29-24 Réponse aux événements socket . . . . . . . 30-8
Utilisation des générateurs de tableau . .29-24 Evénements d’erreurs. . . . . . . . . . . . . . 30-9
Choix des attributs de tableau . . . . . . .29-25 Evénements client . . . . . . . . . . . . . . . . 30-9
Choix des attributs de lignes . . . . . . . .29-25 Evénements serveur. . . . . . . . . . . . . . 30-10
Choix des attributs de colonnes . . . . . .29-25 Evénements d’écoute . . . . . . . . . . . . 30-10
Incorporation de tableaux dans un Evénements de connexions client. . . . . 30-10
document HTML . . . . . . . . . . . . . .29-26 Lectures et écritures sur des connexions
Configuration d’un générateur de socket . . . . . . . . . . . . . . . . . . . . . . 30-11
tableau ensemble de données . . . . . . .29-26 Connexions non bloquantes. . . . . . . . . .30-11
Configuration d’un générateur de Lecture et écriture d’événements . . . . . 30-11
tableau requête . . . . . . . . . . . . . . . .29-26 Connexions bloquantes. . . . . . . . . . . . 30-12
Débogage d’applications serveur . . . . . . 29-27 Utilisation de threads avec des
Débogage d’applications ISAPI et connexions bloquantes . . . . . . . . . . 30-12
NSAPI . . . . . . . . . . . . . . . . . . . . . 29-27 Utilisation de TWinSocketStream . . . . . 30-13
Débogage sous Windows NT . . . . . . . .29-27 Ecriture de threads client. . . . . . . . . . 30-13
Débogage avec Microsoft IIS Server . . . .29-27 Ecriture de threads serveur . . . . . . . . 30-14
Débogage sous MTS . . . . . . . . . . . . .29-28
Débogage avec Personal Web Server
pour Windows 95 . . . . . . . . . . . . . .29-29
Débogage avec Netscape Server
Version 2.0 . . . . . . . . . . . . . . . . . .29-30
Débogage d’applications CGI et
Win-CGI . . . . . . . . . . . . . . . . . . . . 29-31
Simulation du serveur . . . . . . . . . . . .29-31
Débogage en tant que DLL . . . . . . . . .29-31
xvii
Partie IV Définition de l’interface de conception . . . 32-7
Répartition des méthodes . . . . . . . . . . . . 32-8
Création de composants Méthodes statiques . . . . . . . . . . . . . . . 32-8
personnalisés Méthodes virtuelles . . . . . . . . . . . . . . . 32-9
Surcharge des méthodes . . . . . . . . . . . 32-9
Chapitre 31 Membres abstraits d’une classe . . . . . . . 32-10
Présentation générale de la Classes et pointeurs . . . . . . . . . . . . . . 32-10
création d’un composant 31-1 Chapitre 33
La bibliothèque des composants visuels. . . 31-1 Création de propriétés 33-1
Composants et classes. . . . . . . . . . . . . . 31-2 Pourquoi créer des propriétés ? . . . . . . . . 33-1
Comment créer un composant ? . . . . . . . 31-2 Types de propriétés . . . . . . . . . . . . . . . 33-2
Modification de contrôles existants. . . . . . 31-3 Publication des propriétés héritées . . . . . . 33-3
Création de contrôles fenêtrés . . . . . . . . . 31-4
Création de contrôles graphiques. . . . . . . 31-4 Définition des propriétés . . . . . . . . . . . . 33-4
Sous-classement de contrôles Windows . . . 31-4 Déclaration des propriétés. . . . . . . . . . . 33-4
Création de composants non visuels. . . . . 31-5 Stockage interne des données. . . . . . . . . 33-4
Accès direct. . . . . . . . . . . . . . . . . . . . 33-5
Contenu d’un composant ?. . . . . . . . . . . 31-5
Méthodes d’accès . . . . . . . . . . . . . . . . 33-5
Suppression des dépendances . . . . . . . . . 31-5 Méthode read . . . . . . . . . . . . . . . . . . 33-7
Propriétés, méthodes et événements . . . . . 31-6 Méthode write . . . . . . . . . . . . . . . . . 33-7
Propriétés . . . . . . . . . . . . . . . . . . . . 31-6 Valeurs par défaut d’une propriété . . . . . 33-8
Evénements . . . . . . . . . . . . . . . . . . . 31-7 Spécification d’aucune valeur par défaut . 33-8
Méthodes . . . . . . . . . . . . . . . . . . . . 31-7
Encapsulation des graphiques . . . . . . . . . 31-7 Création de propriétés tableau. . . . . . . . . 33-9
Recensement. . . . . . . . . . . . . . . . . . . . 31-8 Stockage et chargement des propriétés . . 33-10
Création d’un nouveau composant. . . . . . 31-8 Utilisation du mécanisme de stockage et
de chargement . . . . . . . . . . . . . . . . 33-10
Utilisation de l’expert composant. . . . . . . 31-9
Spécification des valeurs par défaut. . . . .33-11
Création manuelle d’un composant . . . . 31-11
Détermination du stockage . . . . . . . . . .33-11
Création d’un fichier unité. . . . . . . . . .31-11
Dérivation du composant . . . . . . . . . .31-12
Initialisation après chargement . . . . . . . 33-12
Recensement du composant . . . . . . . . .31-12 Stockage et chargement des propriétés
non publiées . . . . . . . . . . . . . . . . . 33-13
Test des composants non installés . . . . . 31-13 Création de méthodes pour le stockage
et le chargement de valeurs de
Chapitre 32 propriétés . . . . . . . . . . . . . . . . . . 33-13
Programmation orientée objet Redéfinition de la méthode
DefineProperties . . . . . . . . . . . . . . 33-14
et écriture des composants 32-1
Définition de nouvelles classes . . . . . . . . 32-2 Chapitre 34
Dérivation de nouvelles classes . . . . . . . . 32-2 Création d’événements 34-1
Modifier les valeurs par défaut d’une
classe pour éviter les répétitions . . . . . 32-2 Qu’est-ce qu’un événement ?. . . . . . . . . . 34-1
Ajout de nouvelles capacités à une Les événements sont des pointeurs de
classe . . . . . . . . . . . . . . . . . . . . . . 32-3 méthodes . . . . . . . . . . . . . . . . . . . . 34-2
Déclaration d’une nouvelle classe de Les événements sont des propriétés. . . . . 34-2
composant . . . . . . . . . . . . . . . . . . . . 32-3 Les types d’événements sont des types de
Ancêtres, descendants et hiérarchies des pointeurs de méthodes . . . . . . . . . . . . 34-3
classes . . . . . . . . . . . . . . . . . . . . . . . 32-4 Les types gestionnaire d’événement sont
des procédures . . . . . . . . . . . . . . . . 34-3
Contrôle des accès . . . . . . . . . . . . . . . . 32-4 Les gestionnaires d’événements sont
Masquer les détails d’implémentation . . . . 32-5 facultatifs . . . . . . . . . . . . . . . . . . . . 34-4
Définition de l’interface avec le concepteur Implémentation des événements standard . 34-5
des composants. . . . . . . . . . . . . . . . . 32-6
Identification des événements standard. . . 34-5
Définition de l’interface d’exécution . . . . . 32-6
xviii
Evénements standard pour tous les Chapitre 37
contrôles . . . . . . . . . . . . . . . . . . . . 34-5
Evénements standard pour les contrôles Gestion des messages 37-1
standard . . . . . . . . . . . . . . . . . . . . 34-5 Compréhension du système de gestion des
Rendre visibles des événements. . . . . . . . 34-6 messages . . . . . . . . . . . . . . . . . . . . . 37-1
Changement de la gestion des événements Que contient un message Windows ? . . . . 37-2
standard . . . . . . . . . . . . . . . . . . . . . 34-6 Répartition des messages . . . . . . . . . . . 37-2
Définition de vos propres événements. . . . 34-7 Suivi du flux des messages . . . . . . . . . 37-3
Déclenchement de l’événement . . . . . . . . 34-7 Modification de la gestion des messages . . 37-3
Deux sortes d’événements . . . . . . . . . . 34-7 Surcharge de la méthode du gestionnaire . 37-4
Définition du type de gestionnaire . . . . . . 34-8 Utilisation des paramètres d’un message. . 37-4
Notifications simples . . . . . . . . . . . . . 34-8 Interception des messages . . . . . . . . . . . 37-4
Gestionnaires d’événements spécifiques. . 34-8
Création de nouveaux gestionnaires de
Renvoi d’informations à partir du
gestionnaire . . . . . . . . . . . . . . . . . . 34-9 messages . . . . . . . . . . . . . . . . . . . . . 37-5
Déclaration de l’événement . . . . . . . . . . 34-9 Définition de vos propres messages. . . . . 37-5
Les noms d’événement débutent par Déclaration d’un identificateur de
“On” . . . . . . . . . . . . . . . . . . . . . . 34-9 message . . . . . . . . . . . . . . . . . . . . 37-6
Appel de l’événement. . . . . . . . . . . . . . 34-9 Déclaration d’un type enregistrement de
message . . . . . . . . . . . . . . . . . . . . 37-6
Les gestionnaires vides doivent être
valides . . . . . . . . . . . . . . . . . . . . .34-10 Déclaration d’une nouvelle méthode de
Les utilisateurs peuvent surcharger la gestion d’un message. . . . . . . . . . . . . 37-7
gestion par défaut . . . . . . . . . . . . . .34-10
Chapitre 38
Chapitre 35 Accessibilité des composants
Création de méthodes 35-1 au moment de la conception 38-1
Eviter les interdépendances . . . . . . . . . . 35-1 Recensement des composants . . . . . . . . . 38-1
Noms des méthodes. . . . . . . . . . . . . . . 35-2 Déclaration de la procédure Register . . . . 38-2
Protection des méthodes . . . . . . . . . . . . 35-3 Ecriture de la procédure Register . . . . . . 38-2
Méthodes qui doivent être publiques . . . . 35-3 Spécification des composants . . . . . . . . 38-3
Méthodes qui doivent être protégées . . . . 35-3 Spécification de la page de palette . . . . . 38-3
Méthodes abstraites . . . . . . . . . . . . . . . 35-4 Utilisation de la fonction
RegisterComponents. . . . . . . . . . . . . 38-3
Rendre virtuelles des méthodes . . . . . . . . 35-4
Ajout de bitmaps à la palette . . . . . . . . . 38-4
Déclaration des méthodes . . . . . . . . . . . 35-4
Fournir l’aide pour vos composants . . . . . 38-4
Chapitre 36 Création du fichier d’aide . . . . . . . . . . . 38-4
Création des entrées. . . . . . . . . . . . . . 38-5
Graphiques et composants 36-1 Aide contextuelle des composants . . . . . 38-6
Présentation des graphiques . . . . . . . . . . 36-1 Ajout des fichiers d’aide des
Utilisation du canevas. . . . . . . . . . . . . . 36-3 composants . . . . . . . . . . . . . . . . . . 38-7
Travail sur les images . . . . . . . . . . . . . . 36-3 Ajout d’éditeurs de propriétés . . . . . . . . . 38-7
Utilisation d’une image, d’un graphique Dérivation d’une classe éditeur de
ou d’un canevas . . . . . . . . . . . . . . . . 36-4 propriétés . . . . . . . . . . . . . . . . . . . . 38-8
Chargement et stockage des graphiques . . 36-4 Modification de la propriété sous une
forme textuelle . . . . . . . . . . . . . . . . . 38-9
Gestion des palettes . . . . . . . . . . . . . . . 36-5
Affichage de la valeur de la propriété. . . 38-9
Spécification d’une palette pour un
contrôle . . . . . . . . . . . . . . . . . . . . 36-6 Définition de la valeur de la propriété . . 38-9
Réponse aux changements de palette . . . 36-6 Modification globale de la propriété . . . 38-10
Spécification des attributs de l’éditeur . . .38-11
Bitmaps hors écran. . . . . . . . . . . . . . . . 36-6
Recensement de l’éditeur de propriétés. . 38-12
Création et gestion des bitmaps hors
écran . . . . . . . . . . . . . . . . . . . . . . . 36-6 Ajout d’éditeurs de composants. . . . . . . 38-13
Copie des images bitmap. . . . . . . . . . . . 36-7 Ajout d’éléments au menu contextuel . . 38-14
Réponse aux changements . . . . . . . . . . . 36-7 Spécification d’éléments de menu . . . . 38-14
Implémentation des commandes . . . . . 38-15
xix
Modification du comportement suite à Chapitre 41
un double-clic . . . . . . . . . . . . . . . . . 38-15
Ajout de formats de Presse-papiers . . . . 38-16 Personnalisation d’une grille 41-1
Recensement d’un éditeur de Création et recensement du composant . . . 41-1
composants . . . . . . . . . . . . . . . . . . 38-16 Publication des propriétés héritées . . . . . . 41-2
Catégories de propriété . . . . . . . . . . . . 38-17 Modification des valeurs initiales . . . . . . . 41-3
Recensement d’une propriété à la fois. . . 38-18 Redimensionnement des cellules . . . . . . . 41-4
Recensement de plusieurs propriétés en
une seule fois . . . . . . . . . . . . . . . . . 38-18 Remplissage des cellules . . . . . . . . . . . . 41-5
Classes de catégorie de propriété . . . . . . 38-19 Suivi de la date . . . . . . . . . . . . . . . . . 41-5
Catégories de propriété intégrées. . . . . .38-19 Stockage interne de la date . . . . . . . . . 41-6
Dérivation de nouvelles catégories de Accès au jour, au mois et à l’année . . . . 41-6
propriétés . . . . . . . . . . . . . . . . . . .38-20 Génération des numéros de jours . . . . . 41-8
Utilisation de la fonction Sélection du jour en cours . . . . . . . . . . 41-9
IsPropertyInCategory . . . . . . . . . . . . 38-20 Navigation de mois en mois et d’année en
Compilation des composants en paquets . 38-21 année . . . . . . . . . . . . . . . . . . . . . . 41-10
Problèmes d’installation de composants Navigation de jour en jour . . . . . . . . . . 41-11
personnalisés . . . . . . . . . . . . . . . . . 38-21 Déplacement de la sélection. . . . . . . . . .41-11
Fourniture d’un événement OnChange. . 41-12
Chapitre 39 Exclusion des cellules vides. . . . . . . . . 41-12
Modification d’un composant Chapitre 42
existant 39-1 Contrôles orientés données 42-1
Création et recensement du composant . . . 39-1 Création d’un contrôle pour scruter les
Modification de la classe composant. . . . . 39-2 données . . . . . . . . . . . . . . . . . . . . . . 42-2
Surcharge du constructeur . . . . . . . . . . . 39-2 Création et recensement du composant. . . 42-2
Spécification de la nouvelle valeur par Fonctionnement du contrôle en lecture
défaut de la propriété . . . . . . . . . . . . . 39-3 seulement . . . . . . . . . . . . . . . . . . . . 42-3
Ajout de la propriété ReadOnly . . . . . . 42-3
Chapitre 40 Autorisation des mises à jour
Création d’un composant nécessaires . . . . . . . . . . . . . . . . . . . 42-4
Ajout du lien aux données . . . . . . . . . . 42-5
graphique 40-1 Déclaration du champ de classe . . . . . . 42-5
Création et recensement du composant . . . 40-1 Déclaration des propriétés d’accès . . . . . 42-5
Publication des propriétés héritées . . . . . . 40-2 Exemple de déclaration des propriétés
d’accès . . . . . . . . . . . . . . . . . . . . . 42-6
Ajout de fonctionnalités graphiques . . . . . 40-3 Initialisation du lien de données . . . . . . 42-6
Détermination de ce qui doit être dessiné . 40-3 Réponse aux changements de données . . . 42-7
Déclaration du type de la propriété . . . . 40-3
Déclaration de la propriété . . . . . . . . . 40-4 Création d’un contrôle pour modifier les
Ecriture de la méthode d’implémen- données . . . . . . . . . . . . . . . . . . . . . . 42-8
tation . . . . . . . . . . . . . . . . . . . . . . 40-4 Modification de la valeur par défaut de
Surcharge du constructeur et du FReadOnly . . . . . . . . . . . . . . . . . . . 42-9
destructeur. . . . . . . . . . . . . . . . . . . . 40-4 Gestion des messages liés à la souris ou
Modification des valeurs par défaut des au clavier . . . . . . . . . . . . . . . . . . . . 42-9
propriétés . . . . . . . . . . . . . . . . . . . 40-4 Réponse aux messages indiquant la
Publication du crayon et du pinceau . . . . 40-5 manipulation de la souris . . . . . . . . . 42-9
Déclaration des champs de classe . . . . . 40-5 Réponse aux messages indiquant la
Déclaration des propriétés d’accès . . . . . 40-6 manipulation du clavier . . . . . . . . . 42-10
Initialisation des classes ayant un Mise à jour de la classe lien de données
propriétaire . . . . . . . . . . . . . . . . . . 40-7 sur un champ . . . . . . . . . . . . . . . . .42-11
Définition des propriétés des classes Modification de la méthode Change . . . 42-12
ayant un propriétaire . . . . . . . . . . . . 40-7 Mise à jour de l’ensemble de données . . 42-12
Dessin de l’image du composant . . . . . . . 40-8
Adaptation du dessin de la forme . . . . . . 40-9
xx
Chapitre 43 Chapitre 45
Transformation d’une boîte de Création d’un objet COM simple 45-1
dialogue en composant 43-1 Présentation de la création d’un objet
Définition de l’interface du composant . . . 43-2 COM. . . . . . . . . . . . . . . . . . . . . . . . 45-1
Création et recensement du composant . . . 43-2 Conception d’un objet COM . . . . . . . . . . 45-2
Création de l’interface du composant . . . . 43-3 Création d’un objet COM avec l’expert
objet COM . . . . . . . . . . . . . . . . . . . . 45-2
Inclusionde l’unité de la fiche . . . . . . . . . 43-3
Ajout des propriétés de l’interface . . . . . . 43-3 Types d’instanciation des objets COM . . . . 45-3
Ajout de la méthode Execute . . . . . . . . . 43-5 Choix d’un modèle de thread . . . . . . . . . 45-4
Test du composant . . . . . . . . . . . . . . . . 43-6 Ecriture d’un objet supportant le modèle
de thread libre . . . . . . . . . . . . . . . . . 45-5
Partie V Ecriture d’un objet supportant le modèle
de thread apartment . . . . . . . . . . . . . 45-6
Développement d’applications COM Recensement d’un objet COM . . . . . . . . . 45-6
Test d’un objet COM. . . . . . . . . . . . . . . 45-7
Chapitre 44
Présentation des technologies Chapitre 46
COM 44-1 Création d’un contrôleur
COM, spécification et implémentation . . 44-2 Automation 46-1
Extensions de COM. . . . . . . . . . . . . . 44-2 Création d’un contrôleur Automation en
Composantes d’une application COM . . . . 44-3 important une bibliothèque de types . . . . 46-2
Interfaces COM . . . . . . . . . . . . . . . . . . 44-3 Gestion des événements dans un
L’interface COM de base, IUnknown . . . 44-4 contrôleur Automation . . . . . . . . . . . . 46-3
Pointeurs d’interface COM . . . . . . . . . 44-5 Connexion à un serveur et déconnexion
Serveurs COM . . . . . . . . . . . . . . . . . . 44-5 d’un serveur . . . . . . . . . . . . . . . . . . 46-3
CoClasses et fabricants de classes . . . . . 44-6 Contrôle d’un serveur Automation avec
Serveurs en processus, hors processus et une interface double . . . . . . . . . . . . . 46-4
distants. . . . . . . . . . . . . . . . . . . . . 44-6 Contrôle d’un serveur Automation en
Le mécanisme du marshaling. . . . . . . . 44-8 utilisant interface de répartition . . . . . . 46-4
Clients COM . . . . . . . . . . . . . . . . . . . 44-9 Exemple : impression d’un document dans
Extensions de COM . . . . . . . . . . . . . . . 44-9 Microsoft Word . . . . . . . . . . . . . . . . 46-5
Serveurs et contrôleurs Automation . . . . 44-12 Etape 1 : Préparation de Delphi pour cet
Contrôles ActiveX . . . . . . . . . . . . . . . 44-12 exemple . . . . . . . . . . . . . . . . . . . . 46-5
Etape 2 : importation de la bibliothèque
Bibliothèques de types . . . . . . . . . . . . 44-13 de types Word . . . . . . . . . . . . . . . . 46-5
Contenu d’une bibliothèque de types . . .44-13 Etape 3 : utilisation d’un objet interface
Création de bibliothèques de types . . . .44-14 VTable ou de répartition pour contrôler
Quand utiliser les bibliothèques de Microsoft Word . . . . . . . . . . . . . . . . 46-6
types . . . . . . . . . . . . . . . . . . . . . .44-14 Etape 4 : Nettoyage de l’exemple . . . . . . 46-7
Accès aux bibliothèques de types . . . . .44-15 Autres sources d’informations . . . . . . . . 46-8
Avantages des bibliothèques de types. . .44-15
Utilisation des outils de bibliothèques Chapitre 47
de types . . . . . . . . . . . . . . . . . . . .44-16
Pages Active Server . . . . . . . . . . . . . . 44-16 Création d’un serveur Automation 47-1
Documents Active . . . . . . . . . . . . . . . 44-17 Création d’un objet Automation pour une
Objets visuels inter-processus . . . . . . . . 44-17 application . . . . . . . . . . . . . . . . . . . . 47-1
Implémentation des objets COM à l’aide Gestion des événements de l’objet
d’experts . . . . . . . . . . . . . . . . . . . . 44-18 Automation. . . . . . . . . . . . . . . . . . . . 47-3
xxi
Exposition des propriétés, méthodes et Création d’une page de propriétés pour
événements d’une application . . . . . . . . 47-3 un contrôle ActiveX . . . . . . . . . . . . . 48-14
Exposition d’une propriété à l’Automation . 47-3 Création d’une nouvelle page de
Exposition d’une méthode à l’Automation . 47-4 propriétés . . . . . . . . . . . . . . . . . . . 48-15
Exposition d’un événement à Ajout des contrôles à une page de
l’Automation . . . . . . . . . . . . . . . . . . 47-4 propriétés . . . . . . . . . . . . . . . . . . . 48-15
Autres sources d’informations . . . . . . . . . 47-5 Association des contrôles de la page de
Recensement d’une application comme propriétés aux propriétés du contrôle
serveur Automation . . . . . . . . . . . . . . 47-6 ActiveX . . . . . . . . . . . . . . . . . . . . 48-16
Recensement d’un serveur en processus . . 47-6 Actualisation de la page de propriétés . 48-16
Actualisation de l’objet . . . . . . . . . . . 48-16
Recensement d’un serveur hors processus . 47-6
Connexion d’une page de propriétés à
Test et débogage de l’application . . . . . . . 47-6 un contrôle ActiveX. . . . . . . . . . . . . 48-17
Interfaces Automation . . . . . . . . . . . . . . 47-7 Exposition des propriétés d’un contrôle
Interfaces duales . . . . . . . . . . . . . . . . . 47-7 ActiveX . . . . . . . . . . . . . . . . . . . . . 48-17
Interfaces de répartition. . . . . . . . . . . . . 47-8 Recensement d’un contrôle ActiveX . . . . 48-18
Interfaces personnalisées . . . . . . . . . . . . 47-9
Test d’un contrôle ActiveX . . . . . . . . . . 48-19
Marshaling des données . . . . . . . . . . . . 47-9
Déploiement d’un contrôle ActiveX sur le
Types compatibles avec l’Automation . . . . 47-9
Web . . . . . . . . . . . . . . . . . . . . . . . 48-19
Restrictions de type pour le marshaling
automatique . . . . . . . . . . . . . . . . . . 47-10 Paramétrage des options de déploiement
Web. . . . . . . . . . . . . . . . . . . . . . . 48-20
Marshaling personnalisé . . . . . . . . . . . 47-10
Case à cocher Défaut des Options de
déploiement Web. . . . . . . . . . . . . . 48-21
Chapitre 48 Fichier .INF . . . . . . . . . . . . . . . . . . 48-21
Création d’un contrôle ActiveX 48-1 Combinaisons d’options . . . . . . . . . . 48-22
Présentation de la création d’un contrôle Page Projet . . . . . . . . . . . . . . . . . . . 48-22
ActiveX . . . . . . . . . . . . . . . . . . . . . . 48-1 Page Paquets . . . . . . . . . . . . . . . . . . 48-23
Eléments d’un contrôle ActiveX. . . . . . . . 48-2 Paquets utilisés par ce projet . . . . . . . 48-24
Contrôle VCL. . . . . . . . . . . . . . . . . . 48-2 Options CAB . . . . . . . . . . . . . . . . . 48-24
Bibliothèque de types. . . . . . . . . . . . . 48-3 Options de sortie. . . . . . . . . . . . . . . 48-24
Propriétés, méthodes et événements . . . . 48-3 Options de répertoire et URL . . . . . . . 48-24
Page de propriétés. . . . . . . . . . . . . . . 48-3 Page Fichiers supplémentaires . . . . . . . 48-24
Fichiers associés au projet . . . . . . . . . 48-25
Conception d’un contrôle ActiveX . . . . . . 48-3
Options CAB . . . . . . . . . . . . . . . . . 48-25
Génération d’un contrôle ActiveX à partir Options de sortie. . . . . . . . . . . . . . . 48-25
d’un contrôle VCL . . . . . . . . . . . . . . . 48-4 Options de répertoire et URL . . . . . . . 48-25
Définition des licences des contrôles Page Encodage. . . . . . . . . . . . . . . . . 48-25
ActiveX . . . . . . . . . . . . . . . . . . . . . . 48-6 Informations requises . . . . . . . . . . . . 48-26
Génération d’un contrôle ActiveX basé sur Informations facultatives . . . . . . . . . . 48-26
une fiche VCL. . . . . . . . . . . . . . . . . . 48-7 Serveur de date de validité . . . . . . . . 48-26
Manipulation des propriétés, méthodes et Algorithme cryptographique. . . . . . . . 48-27
événements d’un contrôle ActiveX . . . . . 48-9
Ajout de propriétés, méthodes et Chapitre 49
événements supplémentaires. . . . . . . . . 48-9 Utilisation des bibliothèques de
Comment Delphi ajoute les propriétés . .48-10
Comment Delphi ajoute les méthodes . .48-11 types 49-1
Comment Delphi ajoute les L’éditeur de bibliothèques de types. . . . . . 49-2
événements . . . . . . . . . . . . . . . . . .48-11 Barre d’outils . . . . . . . . . . . . . . . . . . . 49-3
Activation de la liaison de données Volet liste des objets . . . . . . . . . . . . . . 49-5
simple avec la bibliothèque de types. . . 48-12 Barre d’état . . . . . . . . . . . . . . . . . . . . 49-6
Activation de la liaison de données Les pages d’informations de type . . . . . . 49-6
simple des contrôles ActiveX dans le Page Attributs . . . . . . . . . . . . . . . . . 49-6
conteneur Delphi . . . . . . . . . . . . . . . 48-13 Page Texte . . . . . . . . . . . . . . . . . . . . 49-7
Pages Indicateurs. . . . . . . . . . . . . . . . 49-7
xxii
Informations de type d’une bibliothèque . . 49-7 Syntaxe pour une énumération . . . . . . 49-29
Page Attributs d’une bibliothèque de Syntaxe pour un alias . . . . . . . . . . . . 49-30
types . . . . . . . . . . . . . . . . . . . . . . . 49-8 Syntaxe pour un enregistrement . . . . . 49-30
Page Utilise d’une bibliothèque de types . . 49-8 Syntaxe pour une union . . . . . . . . . . 49-30
Page Indicateurs d’une bibliothèque de Syntaxe pour un module . . . . . . . . . . 49-31
types . . . . . . . . . . . . . . . . . . . . . . . 49-8 Création d’une nouvelle bibliothèque de
Pages d’une interface . . . . . . . . . . . . . . 49-9 types . . . . . . . . . . . . . . . . . . . . . . 49-31
Page Attributs d’une interface. . . . . . . . . 49-9 Ouverture d’une bibliothèque de types
Indicateurs d’une interface . . . . . . . . . . . 49-9 existante . . . . . . . . . . . . . . . . . . . . 49-32
Membres d’une interface . . . . . . . . . . . 49-10 Ajout d’une interface à une bibliothèque
de types . . . . . . . . . . . . . . . . . . . . 49-32
Méthodes d’une interface . . . . . . . . . .49-10
Propriétés d’une interface . . . . . . . . . .49-11 Ajout de propriétés et méthodes à une
interface ou dispinterface . . . . . . . . . 49-33
Page Paramètres des propriétés et
méthodes . . . . . . . . . . . . . . . . . . .49-12 Ajout d’une CoClasse à une bibliothèque
de types . . . . . . . . . . . . . . . . . . . . 49-34
Informations de type d’une interface de Ajout d’une énumération à une
répartition . . . . . . . . . . . . . . . . . . . 49-14 bibliothèque de types. . . . . . . . . . . . 49-34
Page Attributs d’une interface de Enregistrement et recensement des
répartition . . . . . . . . . . . . . . . . . . . 49-15 informations d’une bibliothèque de
Page Indicateurs d’une interface de types . . . . . . . . . . . . . . . . . . . . . . 49-34
répartition . . . . . . . . . . . . . . . . . . . 49-15 Boîte de dialogue Appliquer les mises
Membres d’une interface de répartition . . 49-15 à jour . . . . . . . . . . . . . . . . . . . . . 49-35
Pages d’une CoClasse . . . . . . . . . . . . . 49-16 Enregistrement d’une bibliothèque de
Page Attributs d’une CoClasse . . . . . . . 49-16 types . . . . . . . . . . . . . . . . . . . . . 49-36
Page Implémente d’une CoClasse . . . . . 49-17 Rafraîchissement de la bibliothèque de
Indicateurs d’une CoClasse . . . . . . . . . 49-17 types . . . . . . . . . . . . . . . . . . . . . 49-36
Recensement d’une bibliothèque de
Informations de type d’une énumération . 49-18 types . . . . . . . . . . . . . . . . . . . . . 49-36
Page Attributs d’une énumération . . . . . 49-18 Exportation d’un fichier IDL. . . . . . . . 49-37
Membres d’une énumération . . . . . . . . 49-19
Déploiement des bibliothèques de types . 49-37
Informations de type d’un alias. . . . . . . 49-19
Page Attributs d’un alias . . . . . . . . . . . 49-19 Chapitre 50
Informations de type d’un Création des objets MTS 50-1
enregistrement. . . . . . . . . . . . . . . . . 49-20
Page Attributs d’un enregistrement . . . . 49-20 Composants Microsoft Transaction Server. . 50-2
Membres d’un enregistrement. . . . . . . . 49-20 Exigences d’un composant MTS . . . . . . . 50-4
Informations de type d’une union . . . . . 49-21 Gestion des ressources avec l’activation
Page Attributs d’une union . . . . . . . . . 49-21 just-in-time et le pooling . . . . . . . . . . . 50-5
Membres d’une union. . . . . . . . . . . . . 49-21 Activation just-in-time . . . . . . . . . . . . . 50-5
Informations de type d’un module. . . . . 49-22 Pooling des ressources . . . . . . . . . . . . . 50-6
Page Attributs d’un module . . . . . . . . . 49-22 Libération des ressources . . . . . . . . . . . 50-6
Membres d’un module . . . . . . . . . . . . 49-22 Pooling des objets . . . . . . . . . . . . . . . . 50-6
Méthodes d’un module. . . . . . . . . . . .49-23 Accès au contexte d’un objet . . . . . . . . . 50-7
Constantes de module . . . . . . . . . . . .49-23 Support transactionnel MTS . . . . . . . . . . 50-7
Création de nouvelles bibliothèques de Attributs transactionnels . . . . . . . . . . . . 50-8
types. . . . . . . . . . . . . . . . . . . . . . . 49-23 Le contexte d’objet contient l’attribut de
Types autorisés . . . . . . . . . . . . . . . . . 49-24 la transaction . . . . . . . . . . . . . . . . . . 50-9
Les SafeArray. . . . . . . . . . . . . . . . . .49-25 Objets avec état et sans état. . . . . . . . . . 50-9
Utilisation de la syntaxe Pascal Objet ou Activation de plusieurs objets pour
IDL . . . . . . . . . . . . . . . . . . . . . . . 49-25 supporter les transactions . . . . . . . . . 50-10
Spécifications des attributs. . . . . . . . . .49-26 Transactions contrôlées par MTS ou par
Syntaxe pour une interface . . . . . . . . .49-27 le client . . . . . . . . . . . . . . . . . . . . 50-10
Syntaxe pour une interface de Avantage des transactions . . . . . . . . . . .50-11
répartition . . . . . . . . . . . . . . . . . . .49-28 Temporisation des transactions . . . . . . . .50-11
Syntaxe pour une CoClasse . . . . . . . . .49-29 Sécurité en fonction des rôles . . . . . . . . 50-12
xxiii
Dispenseurs de ressources . . . . . . . . . . 50-12 Définition d’un objet transaction côté
Dispenseur de ressources BDE . . . . . . . 50-13 client . . . . . . . . . . . . . . . . . . . . . . . 50-21
Gestionnaire de propriétés partagées. . . . 50-13 Définition d’un objet transaction côté
Exemple : Partage de propriétés entre serveur . . . . . . . . . . . . . . . . . . . . . 50-22
les instances d’un objet MTS . . . . . . .50-13 Débogage et test des objets MTS . . . . . . 50-22
Conseils d’utilisation du gestionnaire de
propriétés partagées. . . . . . . . . . . . .50-14 Installation des objets MTS dans un
paquet MTS . . . . . . . . . . . . . . . . . . 50-23
Clients de base et composants MTS . . . . 50-15
Administration des objets MTS avec
Technologies sous-jacentes de MTS, l’explorateur MTS. . . . . . . . . . . . . . . 50-24
COM et DCOM. . . . . . . . . . . . . . . . 50-16
Utilisation de la documentation MTS . . . 50-24
Présentation de la création des objets
MTS . . . . . . . . . . . . . . . . . . . . . . . 50-16 Chapitre 51
Utilisation de l’expert objet MTS . . . . . . 50-16
Choix d’un modèle de thread pour un Création d’une page Active Server 51-1
objet MTS . . . . . . . . . . . . . . . . . . . 50-17 Création d’un objet ASP . . . . . . . . . . . . 51-2
Activités MTS . . . . . . . . . . . . . . . . . . 50-18 Création d’ASP pour des serveurs en et
Définition de l’attribut transactionnel . . . 50-19 hors processus . . . . . . . . . . . . . . . . . 51-3
Transmission de références à des objets . . 50-20 Recensement d’une application comme
Utilisation de la méthode SafeRef . . . . .50-20 objet ASP . . . . . . . . . . . . . . . . . . . . . 51-4
Callbacks . . . . . . . . . . . . . . . . . . . .50-21 Recensement d’un serveur en processus . . 51-4
Recensement d’un serveur hors processus . 51-4
Test et débogage d’une application ASP. . . 51-5
xxiv
Chapitre
1
Introduction
Chapter 1
Contenu de ce manuel
Ce manuel comporte cinq parties décomposées comme suit :
• La partie I, “Programmation avec Delphi,” décrit la manière de concevoir des
applications Delphi généralistes. Cette partie donne des détails sur les
techniques de programmation utilisables dans toute application Delphi. Elle
décrit, par exemple, la manière d’utiliser les objets courants de la bibliothèque
de composants visuels qui simplifient la programmation de l’interface
utilisateur comme la gestion de chaînes, la manipulation de texte,
l’implémentation des boîtes de dialogue standard Windows et les barres
d’outils. Elle contient également des chapitres décrivant la manipulation des
graphiques et la gestion des erreurs et des exceptions, l’utilisation des DLL,
l’automation OLE et l’écriture d’applications internationales.
Le chapitre sur le déploiement aborde les opérations nécessaires pour
distribuer votre application auprès de ses utilisateurs. Ce chapitre donne des
informations sur les options de compilation, l’utilisation de InstallShield
Express, les problèmes de droits de distribution et sur la manière de
déterminer les paquets, DLL et autres bibliothèques qu’il faut utiliser pour
générer la version distribuée d’une application.
Introduction 1-1
Contenu de ce manuel
Conventions typographiques
Ce manuel utilise les polices et les symboles décrits dans le tableau suivant pour
mettre en évidence des parties particulières du texte :
Introduction 1-3
1-4 Guide du développeur
Partie
I
Programmation avec Delphi
Part I
représenté dans la fiche par une icône qui n’apparaît pas à l’exécution. Vous
pouvez manipuler les propriétés et événements de TDataSource à l’aide de
l’inspecteur d’objet comme pour un contrôle visuel.
Quand vous écrivez vos propres classes en Pascal Objet, elles doivent descendre
de TObject. En dérivant de nouvelles classes de la classe de base de la VCL (ou
de l’un de ses descendants), vous fournissez à vos classes des fonctionnalités
essentielles tout en garantissant qu’elles peuvent fonctionner avec la VCL.
TObject
TComponent
TControl
Portée et qualificateurs
La portée détermine l’accessibilité des champs, propriétés et méthodes d’un objet.
Tous les membres déclarés par un objet sont accessibles dans l’objet et dans ses
descendants. Même si le code d’implémentation d’une méthode apparaît hors de
la déclaration de l’objet, la méthode reste dans la portée de l’objet car elle est
déclarée dans la déclaration de l’objet.
Quand vous écrivez du code pour implémenter une méthode qui désigne les
propriétés, méthodes ou champs de l’objet dans lequel la méthode est déclarée,
vous n’avez pas besoin de préfixer ces identificateurs avec le nom de l’objet. Si,
par exemple, vous placez un bouton dans une nouvelle fiche, vous pouvez écrire
le gestionnaire d’événement suivant pour l’événement OnClick du bouton :
procedure TForm1.Button1Click(Sender: TObject);
begin
Color := clFuchsia;
Button1.Color := clLime;
end;
La première instruction est équivalente à :
Form1.Color := clFuchsia
Il n’est pas nécessaire de qualifier Color avec Form1 car la méthode Button1Click
fait partie de TForm1 ; les identificateurs placés dans la méthode sont alors dans
la portée de l’instance de TForm1 où la méthode a été déclarée. Par contre, la
seconde instruction désigne la couleur de l’objet bouton, pas celle de la fiche dans
laquelle le gestionnaire d’événement est déclaré, elle doit donc être qualifiée.
Delphi crée un fichier unité séparé (du code source) pour chaque fiche. Si vous
souhaitez accéder aux composants d’une fiche depuis le fichier unité d’une autre
fiche, vous devez qualifier les noms de composants de la manière suivante :
Form2.Edit1.Color := clLime;
De la même manière, vous pouvez accéder aux méthodes d’un composant d’une
autre fiche, par exemple :
Form2.Edit1.Clear;
Pour accéder aux composants de Form2 depuis le ficher unité de Form1, vous
devez également ajouter l’unité de Form2 à la clause uses de l’unité de Form1.
La portée d’un objet s’étend aux descendants de l’objet. Vous pouvez néanmoins
redéclarer un champ, une propriété ou une méthode dans un objet descendant.
De telles redéclarations masquent ou surchargent le membre hérité.
Pour davantage d’informations sur la portée, l’héritage et la clause uses, voir le
Guide du langage Pascal Objet.
AForm est de type TForm et DataForm est de type TDataForm. Comme TDataForm
est un descendant de TForm, l’instruction d’affectation suivante est légale :
AForm := DataForm;
Supposez que vous remplissiez le gestionnaire d’événement de l’événement
OnClick d’un bouton. Quand le bouton est choisi, le gestionnaire d’événement de
l’événement OnClick est appelé. Chaque gestionnaire d’événement a un
paramètre Sender de type TObject :
procedure TForm1.Button1Click(Sender: TObject);
begin
ƒ
end;
Comme Sender est de type TObject, tout objet peut être affecté à Sender. La valeur
de Sender est toujours le contrôle ou le composant qui répond à l’événement.
Vous pouvez tester Sender pour déterminer le type du composant ou du contrôle
qui a appelé le gestionnaire d’événement en utilisant le mot réservé is. Par
exemple :
if Sender is TEdit then
FaireQuelquechose
else
FaireAutreChose;
Outre les champs, propriétés et méthodes que vous avez défini, TEmployee hérite
de toutes les méthodes de TObject. Vous pouvez placer une déclaration de type
comme celle-ci dans la partie interface ou dans la partie implementation d’une
unité et créer des instances de la nouvelle classe en appelant la méthode Create
que TEmploye hérite de TObject :
var
Employe: TEmploye;
begin
Employe := TEmploye.Create;
end;
La méthode Create est appelée un constructeur. Elle alloue la mémoire pour un
objet nouvellement instancié et renvoie une référence sur l’objet.
Les composants d’une fiche sont créés et détruits automatiquement par Delphi.
Mais si vous écrivez votre propre code pour instancier des objets, vous êtes
responsable de leur libération. Chaque objet hérite de TObject une méthode
Destroy (appelée un destructeur). Néanmoins, pour détruire un objet, vous devez
toujours appeler la méthode Free (également héritée de TObject) car Free vérifie
que l’objet existe encore avant d’appeler Destroy. Par exemple :
Employe.Free
détruit l’objet Employe et libère sa mémoire.
Composants et appartenance
Delphi dispose d’un mécanisme intégré de gestion de la mémoire qui permet à
un composant d’être responsable de la libération d’un autre composant. On dit
que le premier est propriétaire du second. La mémoire d’un composant
appartenant à un autre est automatiquement libérée quand la mémoire du
propriétaire est libérée. Le propriétaire d’un composant (valeur de sa propriété
Owner) est déterminé par un paramètre transmis au constructeur lors de la
création du composant. Par défaut, une fiche possède tous les composants placés
dedans et elle-même appartient à l’application. Ainsi, quand l’application est
arrêtée, la mémoire de toutes les fiches et de leurs composants est libérée.
Cette notion de propriétaire ne s’applique qu’à TComponent et à ses descendants.
Si vous créez un objet TStringList ou TCollection (même s’il est associé à une
fiche), c’est à vous de libérer l’objet.
Remarque Ne confondez pas le propriétaire d’un composant avec son parent. Voir “Propriétés
du parent” à la page 2-12.
L’aide en ligne propose des informations sur les composants de la palette par
défaut. Cependant, les composants des pages ActiveX et Exemples sont proposés
uniquement à titre d’exemple et ne sont pas documentés.
• Propriétés de glisser-déplacer
• Propriétés de glisser-empiler
Ces propriétés sont héritées de TControl mais elles ne sont publiées (elles
apparaissent dans l’inspecteur d’objet) que pour les composants où elles sont
applicables. Ainsi, TImage ne publie pas la propriété Color car sa couleur est
déterminée par l’image qu’il affiche.
Propriétés d’affichage
Quatre propriétés définissent l’aspect général d’un contrôle :
• BorderStyle spécifie si le contrôle a une bordure.
• Color spécifie la couleur de fond d’un contrôle.
• Ctrl3D spécifie si le contrôle a un aspect 3D ou un bord plat.
• Font modifie la couleur, le nom, le style ou la taille du texte.
Propriétés du parent
Pour conserver une présentation homogène dans une application, vous pouvez
donner à un contrôle le même aspect que son conteneur, appelé son parent, en
initialisant les propriétés parent... à True. Si, par exemple, vous placez un bouton
dans une fiche et initialisez la propriété ParentFont du bouton à True, les
modifications de la propriété Font de la fiche sont automatiquement répercutées
sur le bouton (et aux autres enfants de la fiche). Si, ultérieurement, vous
modifiez la propriété Font du bouton, la valeur spécifiée est prise en compte et la
propriété ParentFont passe automatiquement à False.
Remarque Ne confondez pas le parent d’un composant avec son propriétaire. Voir
“Composants et appartenance” à la page 2-10.
Propriétés de déplacement
Plusieurs propriétés déterminent comment les utilisateurs peuvent se déplacer
entre les divers contrôles d’une fiche :
• Caption contient la chaîne de texte qui intitule un composant. Pour souligner un
caractère d’une chaîne, faites-le précéder d’un caractère &. Ce type de caractère
est appelé un caractère accélérateur. L’utilisateur peut alors accéder au contrôle
ou à l’élément de menu en appuyant sur Alt et sur le caractère souligné.
Propriétés de glisser-déplacer
Deux propriétés des composants affectent le comportement du glisser-déplacer :
• DragMode détermine la manière dont un glisser commence. Par défaut,
DragMode a la valeur dmManual et vous devez appeler la méthode BeginDrag
pour commencer un glisser. Si DragMode a la valeur dmAutomatic, le glisser
commence dès que le bouton de la souris est enfoncé.
• DragCursor détermine la forme du pointeur de la souris quand il se trouve au-
dessus d’un composant qui accepte un objet en train de glisser.
Propriétés de glisser-empiler
Les propriétés suivantes des composants contrôlent le comportement de glisser-
empiler :
• DockSite
• DragKind
• DragMode
• FloatingDockSiteClass
• AutoSize
Pour davantage d’informations, voir “Implémentation du glisser-empiler dans les
contrôles” à la page 6-4.
Contrôles texte
Dans de nombreuses applications, l’utilisateur doit saisir ou consulter du texte.
Le type de contrôle à employer pour contenir les informations dépend de la
taille et du format des informations.
Utilisez ce
composant : Quand vous voulez :
Edit Modifier une seule ligne de texte.
Memo Modifier plusieurs lignes de texte.
MaskEdit Utiliser un format particulier, par exemple celui d’un code postal ou
d’un numéro de téléphone.
RichEdit Modifier une quantité illimitée de texte ou utiliser du texte mis en
forme.
Utilisez ce
composant : Quand l’utilisateur doit :
ScrollBar sélectionner des valeurs dans un intervalle continu.
TrackBar sélectionner des valeurs dans un intervalle continu (visuellement plus
parlant qu’une barre de défilement).
UpDown sélectionner une valeur à l’aide d’un incrémenteur associé à un
composant de saisie
HotKey entrer des séquences clavier Ctrl/Maj/Alt.
Barres de défilement
Le composant barre de défilement est une barre de défilement Windows, utilisée
pour faire défiler le contenu d’une fenêtre, d’une fiche ou d’un autre contrôle. Le
code écrit dans le gestionnaire d’événement OnScroll détermine comment la
fenêtre, la fiche ou le contrôle se comporte quand l’utilisateur fait défiler la barre
de défilement.
Le composant barre de défilement est rarement utilisé car la plupart des
composants visuels disposent de leurs propres barres de défilement sans
nécessiter de programmation. Ainsi, TForm propose les propriétés VertScrollBar et
HorzScrollBar qui configurent automatiquement des barres de défilement pour la
fiche. Pour créer une région défilante dans une fiche, utilisez TScrollBox.
• Par défaut, l’utilisateur peut se déplacer d’une graduation vers le haut ou vers
le bas en utilisant les touches de déplacement correspondantes. Affectez
LineSize pour changer cet incrément.
• Affectez PageSize pour déterminer le nombre de graduations du déplacement
quand l’utilisateur appuie sur les touches Pg. Haut et Pg. Bas.
Contrôle séparateur
Un séparateur placé entre deux contrôles alignés permet aux utilisateurs de
redimensionner les contrôles. Utilisé avec des composants comme les volets ou
les boîtes de groupe, les séparateurs vous permettent de décomposer une fiche
en plusieurs volets contenant chacun plusieurs contrôles.
Après avoir placé un volet ou un autre contrôle dans une fiche, ajoutez un
séparateur ayant le même alignement que le contrôle. Le dernier contrôle doit
être aligné sur le client afin qu’il remplisse tout l’espace restant quand les autres
sont redimensionnés. Vous pouvez, par exemple, placer un volet sur le bord
gauche d’une fiche et initialiser sa propriété Alignment à alLeft puis placer un
séparateur (ayant également l’alignement alLeft) à droite du volet, et enfin placer
un autre volet (avec l’alignement alLeft ou alClient) à droite du séparateur.
Initialisez MinSize afin se spécifier la taille minimum que le séparateur doit
laisser quand il redimensionne le contrôle adjacent. Initialisez Beveled à True pour
donner au séparateur un aspect 3D.
Contrôles bouton
Les utilisateurs cliquent sur les contrôles bouton pour initier des actions. En
double-cliquant sur un bouton à la conception, vous affichez le gestionnaire
d’événement OnClick du bouton dans l’éditeur de code.
• Affectez la valeur True à la propriété Cancel pour que le bouton déclenche son
événement OnClick quand l’utilisateur appuie sur Echap.
• Affectez la valeur True à la propriété Default pour que la touche Entrée
déclenche l’événement OnClick du bouton.
Boutons bitmap
Un bouton bitmap (BitBtn) est un contrôle bouton qui contient une image bitmap.
• Pour attribuer un bitmap personnalisé à votre bouton, affectez la propriété
Glyph.
• Utilisez la propriété Kind pour configurer automatiquement un bouton avec
un glyphe et un comportement par défaut.
• Par défaut, le glyphe est à gauche du texte. Pour le déplacer, utilisez la
propriété Layout.
• Le glyphe et le texte sont automatiquement centrés dans le bouton. Pour
changer leur position, utilisez la propriété Margin. Margin détermine le
nombre de pixels entre le bord de l’image et le bord du bouton.
• Par défaut, l’image et le texte sont séparés par 4 pixels. Utilisez Spacing pour
augmenter ou réduire cette distance.
• Les boutons bitmap peuvent avoir 3 états : haut, bas et enfoncé. Affectez la valeur
3 à la propriété NumGlyphs pour attribuer un bitmap différent à chaque état.
Turboboutons
Les turboboutons, qui affichent généralement une image, peuvent fonctionner en
groupe. Ils sont souvent utilisés avec des volets pour créer des barres d’outils.
• Pour faire fonctionner des turboboutons en groupe, affectez à la propriété
GroupIndex de tous les boutons la même valeur non-nulle.
• Par défaut, des turboboutons apparaissent à l’état haut (non sélectionné). Pour
afficher un turbobouton à l’état sélectionné, affectez la valeur True à sa
propriété Down.
Cases à cocher
Une case à cocher est une bascule qui propose à l’utilisateur deux ou trois choix.
• Affectez True à Checked pour que la case soit cochée par défaut.
• Affectez True à AllowGrayed pour que la case à cocher puisse prendre trois
états : cochée, non-cochée et grisée.
• La propriété State indique si la case est cochée (cbChecked), non-cochée
(cbUnchecked) ou grisée (cbGrayed).
Boutons radio
Les boutons radio proposent un ensemble de choix mutuellement exclusifs. Vous
pouvez utiliser des composants bouton radio individuels ou utiliser le composant
groupe de boutons radio qui regroupe automatiquement des boutons radio. Pour
davantage d’informations, voir “Regroupement de composants” à la page 2-21.
Barres d’outils
Les barres d’outils permettent aisément d’organiser et de gérer des contrôles
visuels. Vous pouvez créer une barre d’outils à partir d’un composant volet et de
turboboutons, ou utiliser le composant ToolBar puis choisir Nouveau bouton dans
son menu contextuel pour chaque bouton à ajouter. L’utilisation de cette dernière
méthode présente plusieurs avantages. Les boutons d’une barre d’outils ont
automatiquement des dimensions et un espacement homogènes, les autres
contrôles conservent leur position et hauteur relatives ; les contrôles peuvent
automatiquement passer à la ligne s’il n’y a pas assez de place horizontalement.
Le composant ToolBar propose également des options comme la transparence, les
bordures en relief et les espaces et des séparations pour regrouper des contrôles.
Barres multiples
Une barre multiple contient des contrôles enfant qui peuvent être déplacés ou
redimensionnés de manière indépendante. Chaque contrôle se trouve dans une
bande indépendante. L’utilisateur positionne les contrôles en utilisant la poignée
de redimensionnement à gauche de chaque bande.
La barre multiple exige, à la conception et à l’exécution, une version 4.70, ou
ultérieure, de COMCTL32.DLL (qui se trouve généralement dans le répertoire
WINDOWS\SYSTEM ou WINDOWS\SYSTEM32).
• La propriété Bands contient une collection d’objets TCoolBand. A la conception,
vous pouvez ajouter, retirer ou modifier les bandes à l’aide de l’éditeur de
bandes. Pour l’ouvrir, sélectionnez la propriété Bands dans l’inspecteur d’objet
puis double-cliquez dans la colonne des valeurs à droite ou cliquez sur le
bouton points de suspension (...). Vous pouvez également ajouter des bandes
simplement en ajoutant de nouveaux contrôles fenêtrés de la palette.
Gestion de listes
Les listes proposent à l’utilisateur une collection d’éléments dans laquelle il peut
choisir. Plusieurs composants affichent des listes :
Utilisez ce
composant : Pour afficher :
ListBox Une liste de chaînes de texte.
CheckListBox Une liste avec une case à cocher devant chaque élément.
ComboBox Une boîte de saisie avec une liste surgissante déroulante.
TreeView Une liste hiérarchique.
ListView Une liste d’éléments (déplaçables) avec éventuellement des icônes,
des en-têtes et des colonnes.
DateTimePicker Une boîte liste permettant de saisir des dates ou des heures.
MonthCalendar Un calendrier permettant de sélectionner des dates.
Boîtes à options
Une boîte à options combine une boîte de saisie et une liste déroulante. Quand
les utilisateurs saisissent des données, en entrant du texte dans la boîte de saisie
ou en sélectionnant un élément de la liste, la valeur de la propriété Text change.
Utilisez la propriété Style pour spécifier le type de boîte à options que vous
souhaitez utiliser :
• Utilisez csDropdown si vous voulez une boîte de saisie avec une liste
déroulante. Utilisez csDropDownList pour que la boîte de saisie soit en lecture
seule (ce qui oblige les utilisateurs à sélectionner dans la liste). Initialisez la
propriété DropDownCount pour changer le nombre d’éléments affichés dans la
liste.
• Utilisez csSimple pour créer une boîte à options avec une liste fixe qui reste
toujours ouverte. Prenez soin de redimensionner la boîte à options pour que
les éléments de la liste soient affichés.
• Utilisez csOwnerDrawFixed ou csOwnerDrawVariable pour créer des boîtes à
options dessinées par le propriétaire qui affichent des éléments graphiques ou de
hauteur variable. Pour plus d’informations sur les contrôles dessinés par le
propriétaire, voir “Ajout de graphiques à des contrôles” à la page 6-13.
Vues arborescentes
Une vue arborescente affiche des éléments dans une table des matières indentée.
Le contrôle propose des boutons qui permettent de développer ou de réduire les
noeuds. Vous pouvez inclure des icônes en plus du libellé des éléments et
afficher différentes icônes pour indiquer si un noeud est développé ou réduit.
Vous pouvez également inclure des éléments graphiques, par exemple des cases
à cocher, afin de refléter des informations sur l’état des éléments.
• Indent spécifie le nombre de pixels qui séparent horizontalement les éléments
de leur parents.
• ShowButtons active l’affichage des boutons '+' et '–' pour indiquer si un
élément peut être développé.
• ShowLines active l’affichage de lignes de connexion qui montrent les relations
hiérarchiques.
• ShowRoot détermine si des lignes connectent les éléments racine.
Vues liste
Les vues liste affichent des listes dans divers formats. Utilisez la propriété
ViewStyle pour choisir le type de liste utilisé :
• vsIcon et vsSmallIcon affichent chaque élément sous la forme d’une icône avec
un libellé. Les utilisateurs peuvent faire glisser les éléments dans la fenêtre de
la vue liste.
• vsList affiche les éléments comme icônes libellées qui ne peuvent pas être
déplacées.
• vsReport affichent les éléments à raison d’un par ligne avec des informations
organisées en colonnes. La colonne de gauche contient une petite icône et un
libellé et les autres colonnes contiennent des sous-éléments spécifiés par
l’application. Utilisez la propriété ShowColumnHeaders afin d’afficher des en-
têtes de colonne.
Regroupement de composants
Une interface utilisateur graphique est plus facile à utiliser quand des contrôles
et les contrôles associés sont présentés dans des groupes. Delphi propose
plusieurs composants permettant de regrouper des composants :
Utilisez ce
composant : Pour :
GroupBox Une boîte groupe standard avec un titre.
RadioGroup Un groupe simple de boutons radio.
Panel Un groupe de contrôles plus flexible visuellement.
ScrollBox Une zone défilante contenant des contrôles.
TabControl Un ensemble d’onglets (du type classeur) mutuellement exclusifs.
PageControl Un ensemble d’onglets (du type classeur) mutuellement exclusifs avec
les pages correspondantes, chacune pouvant contenir d’autres
contrôles.
HeaderControl Des en-têtes de colonne redimensionnables.
Volets
Le composant volet constitue un conteneur générique pour d’autres contrôles. Il
est possible d’aligner des volets dans la fiche pour conserver la même position
relative quand la fiche est redimensionnée. La propriété BorderWidth détermine la
largeur, en pixels, de la bordure entourant un volet.
Boîtes de défilement
Les boîtes de défilement permettent de créer des zones défilantes à l’intérieur d’une
fiche. Souvent, les applications ont besoin d’afficher plus d’informations qu’il ne
peut apparaître dans une zone particulière. Certains contrôles, comme les boîtes
liste, les mémos ou les fiches mêmes, peuvent automatiquement faire défiler leur
contenu. Les boîtes de défilement vous offrent davantage de souplesse en vous
permettant de définir arbitrairement une zone défilante dans une fiche.
Comme les volets et les boîtes groupe, les boîtes de défilement contiennent
d’autres contrôles. Mais, normalement une boîte de défilement est invisible. Si les
contrôles qu’elle contient ne peuvent rentrer dans sa partie visible, la boîte de
défilement affiche automatiquement des barres de défilement.
Contrôles onglets
Le composant contrôle onglets a l’aspect des séparateurs d’un classeur. Vous
pouvez créer des onglets en modifiant la propriété Tabs à l’aide de l’inspecteur
d’objet ; chaque chaîne de Tabs représente un onglet. Le contrôle onglets est un
simple volet avec un seul ensemble de composants dedans. Pour changer l’aspect
du contrôle quand les onglets sont sélectionnés, écrivez un gestionnaire
d’événement OnChange. Pour créer une boîte de dialogue multipage, utilisez
plutôt un contrôle pages.
Contrôles pages
Le composant contrôle pages est un ensemble de pages utilisé pour constituer
une boîte de dialogue multipage. Pour créer une nouvelle page dans le contrôle
page, cliquez avec le bouton droit de la souris sur le contrôle pages et choisissez
Nouvelle page.
Contrôles en-tête
Un contrôle en-tête est un ensemble d’en-têtes de colonnes que l’utilisateur peut
sélectionner ou redimensionner à l’exécution. Modifiez la propriété Sections du
contrôle pour ajouter ou modifier les en-têtes.
Rétroaction visuelle
Il existe plusieurs moyens de donner à l’utilisateur des informations sur l’état
d’une application. Par exemple, certains composants, dont TForm, disposent de la
propriété Caption qui peut être définie à l’exécution. Vous pouvez également
créer des boîtes de dialogue pour afficher des messages. De plus, les composants
Utilisez ce composant
ou cette propriété : Pour :
Label et StaticText Afficher du texte non modifiable.
StatusBar Afficher une zone d’état (généralement en bas d’une fenêtre).
ProgressBar Afficher le pourcentage effectué d’une tâche donnée.
Hint et ShowHint Activer les conseils d’aide (appelés aussi bulles d’aide).
HelpContext et HelpFile Effectuer la liaison avec le système d’aide en ligne.
Barres d’état
Même si vous pouvez utiliser un volet pour créer une barre d’état, il est plus
simple d’utiliser le composant barre d’état. Par défaut, la propriété Align d’une
barre d’état a la valeur alBottom, ce qui gère à la fois la position et la taille.
Généralement une barre d’état est divisée en plusieurs zones de texte. Pour créer
des zones, modifiez la propriété Panels avec l’inspecteur d’objet et spécifiez les
propriétés Width, Alignment et Text de chaque volet à l’aide de l’éditeur de
volets. La propriété Text contient le texte affiché dans le volet.
Barres de progression
Quand une application effectue une opération longue, vous pouvez utiliser une
barre de progression pour indiquer le pourcentage réalisé de l’opération. Une
barre de progression affiche une ligne pointillée qui progresse de gauche à droite.
Figure 2.4 Une barre de progression
Grilles
Les grilles affichent des informations disposées en lignes et en colonnes. Si vous
concevez une application de base de données, utilisez les composants TDBGrid et
TDBCtrlGrid décrits dans le chapitre 26, “Utilisation de contrôles de données”.
Sinon, utilisez une grille de dessin ou une grille de chaînes standard.
Grilles de dessin
Une grille de dessin (TDrawGrid) affiche des données quelconques dans un
format tabulaire. Ecrivez un gestionnaire d’événement OnDrawCell pour remplir
les cellules de la grille.
• La méthode CellRect renvoie les coordonnées écran de la cellule spécifiée alors
que la méthode MouseToCell renvoie la colonne et la ligne de la cellule se
trouvant aux coordonnées écran spécifiées. La propriété Selection indique les
limites de la sélection de cellules en cours.
• La propriété TopRow détermine la ligne qui apparaît en haut de la grille. La
propriété LeftCol détermine la première colonne visible sur la gauche de la
grille. VisibleColCount et VisibleRowCount indiquent, respectivement, le nombre
de colonnes et de lignes visibles dans la grille.
• Vous pouvez modifier la largeur et la hauteur d’une colonne ou d’une ligne
en utilisant les propriétés ColWidths et RowHeights. Définissez l’épaisseur des
lignes du quadrillage de la grille avec la propriété GridLineWidth. Ajoutez des
barres de défilement à la grille en utilisant la propriété ScrollBars.
• Vous pouvez spécifier les colonnes ou les lignes fixes (qui ne défilent pas) à
l’aide des propriétés FixedCols et FixedRows. Attribuez une couleur aux
colonnes et aux lignes fixes en utilisant la propriété FixedColor.
• Les propriétés Options, DefaultColWidth et DefaultRowHeight affectent également
l’aspect et le comportement de la grille.
Grilles de chaînes
Le composant grille de chaînes est un descendant de TDrawGrid spécialisé afin
de simplifier l’affichage de chaînes. La propriété Cells énumère les chaînes pour
chaque cellule de la grille ; la propriété Objects énumère les objets associés à
chaque chaîne. Il est possible d’accéder à toutes les chaînes et objets associés
d’une colonne ou d’une ligne donnée en utilisant les propriétés Cols et Rows.
Affichage graphique
Les composants suivants facilitent l’incorporation d’éléments graphiques dans
une application.
Utilisez ce
composant : Pour afficher :
Image des fichiers graphiques.
Shape des formes géométriques.
Bevel des lignes et des cadres en 3D.
PaintBox des graphiques dessinés par l’application à l’exécution.
Animate des fichiers AVI.
Images
Le composant image affiche une image graphique : bitmap, icône ou métafichier.
La propriété Picture spécifie l’image à afficher. Utilisez les propriétés Center,
AutoSize, Stretch et Transparent pour spécifier les options d’affichage.
Formes
Le composant forme affiche une forme géométrique. C’est un contrôle non
fenêtré qui ne peut donc pas recevoir la focalisation. La propriété Shape spécifie
la forme du contrôle. Pour modifier la couleur de la forme ou lui ajouter un
motif, utilisez la propriété Brush qui contient un objet TBrush. Les propriétés
Color et Style de TBrush contrôlent la manière dont la forme est dessinée.
Biseaux
Le composant biseau est une ligne qui peut apparaître en relief ou en creux.
Certains composants comme TPanel disposent de propriétés intégrées pour créer
des contours biseautés. Quand ces propriétés ne sont pas disponibles, utilisez un
composant TBevel pour créer des contours, des boîtes ou des cadres biseautés.
Boîtes à peindre
Le composant boîte à peindre permet à une application de dessiner dans une
fiche. Ecrivez un gestionnaire d’événement OnPaint pour restituer directement
l’image dans le canevas (Canvas) de la boîte à peindre. Il n’est pas possible de
dessiner hors des limites d’une boîte à peindre. Pour davantage d’informations,
voir “Présentation de la programmation relative aux graphiques” à la page 7-1.
Contrôles animation
Le composant animation est une fenêtre qui affiche silencieusement une séquence
vidéo AVI. Une séquence AVI est composée d’une série de plans bitmap, comme
un film. Les séquences AVI peuvent être sonorisées, mais les contrôles animation
ne fonctionnent qu’avec les séquences AVI silencieuses. Les fichiers utilisés
doivent être des fichiers AVI non compressés ou des séquences AVI compressées
en utilisant l’algorithme RLE.
Appel de méthodes
Une méthode s’appelle comme une procédure ou une fonction ordinaire. Ainsi,
les contrôles visuels disposent de la méthode Repaint qui rafraîchit l’image du
contrôle à l’écran. Vous pouvez appeler la méthode Repaint d’un objet grille de
dessin de la manière suivante :
DrawGrid1.Repaint;
Comme pour les propriétés, c’est la portée d’une méthode qui impose ou pas
l’utilisation de qualificateurs. Par exemple, pour redessiner une fiche depuis le
gestionnaire d’événement de l’un des contrôles enfant de la fiche, il n’est pas
nécessaire de préfixer l’appel de méthode avec le nom de la fiche :
procedure TForm1.Button1Click(Sender: TObject);
begin
Repaint;
end;
Pour davantage d’informations sur la portée, voir “Portée et qualificateurs” à la
page 2-7.
4 A l’intérieur du bloc begin...end, entrez le code qui doit être exécuté quand
l’utilisateur sélectionne la commande de menu.
Pour associer un élément de menu à un gestionnaire d’événement OnClick
existant :
1 Ouvrez le concepteur de menus en double-cliquant sur un objet MainMenu ou
PopupMenu.
2 Sélectionnez un élément de menu dans le concepteur de menus. Dans
l’inspecteur d’objet, vérifiez qu’une valeur est attribuée à la propriété Name de
l’élément.
3 Dans la page Evénements de l’inspecteur d’objet, cliquez sur le bouton flèche
vers le bas à côté de OnClick afin d’ouvrir une liste des gestionnaires
d’événements existants. La liste ne propose que les gestionnaires d’événements
écrits pour des événements OnClick dans la fiche. Sélectionnez dans la liste en
cliquant sur un nom de gestionnaire d’événement.
L’exemple suivant charge une copie du fichier WIN.INI dans un champ mémo et
en fait une copie de sauvegarde nommée WIN.BAK.
procedure EditWinIni;
var
FileName: string;{ Stocke le nom du fichier }
begin
FileName := 'C:\WINDOWS\WIN.INI';{ Définit le nom du fichier }
with Form1.Memo1.Lines do
begin
LoadFromFile(FileName);{ Lit le fichier }
SaveToFile(ChangeFileExt(FileName, '.BAK'));{ Enregistre dans un fichier de sauvegarde
}
end;
end;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Déclarations privées }
public
{ Déclarations publiques }
ClickList: TStrings;{ déclare le champ }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
Vous pouvez, par exemple, utiliser IndexOf pour déterminer si un nom de fichier
donné se trouve dans les éléments (Items) d’une boîte liste :
if FileListBox1.Items.IndexOf('WIN.INI') > -1 ...
Sujets de programmation
Chapter 3
3
généraux
Ce chapitre décrit les principes de base des formes courantes de programmation
dans Delphi :
• Gestion des exceptions
• Utilisation des interfaces
• Utilisation des chaînes
• Utilisation des fichiers
imbriqué
Vous pouvez également utiliser des blocs imbriqués afin de définir une gestion
locale, pour des exceptions spécifiques, qui redéfinit la gestion du bloc
environnant. Conceptuellement, cela peut se représenter de la manière suivante :
try
( code protégé)
bloc de gestion
des exceptions
try
bloc de gestion
des exceptions
imbriqué
begin
ADividend := 0;
GetMem(APointer, 1024);{ allouer 1Ko de mémoire }
try
AnInteger := 10 div ADividend;{ cela génère une erreur }
finally
FreeMem(APointer, 1024);{ malgré l’erreur, l’exécution reprend ici }
end;
end;
Les instructions placées dans le code de conclusion ne dépendent pas de
l’apparition d’une exception. Si les instructions de la partie try ne déclenchent
pas d’exceptions, l’exécution se poursuit quand même dans le code de conclusion
placé dans la partie finally.
Pour une liste des types d’exception RTL, voir l’unité SysUtils dans le système
d’aide.
Exemple Le bloc suivant est le squelette d’un exemple gérant toutes les exceptions de
calcul entier de manière spécifique :
try
{ instructions effectuant des opérations de calcul entier }
except
on EIntError do { gestion spéciale des erreurs de calcul entier };
end;
Vous pouvez toujours définir des gestionnaires plus spécifiques pour des
exceptions plus spécifiques. Vous devez juste placer les gestionnaires spécifiques
avant le gestionnaire générique car l’application recherche les gestionnaires dans
leur ordre d’apparition et exécute le premier gestionnaire applicable trouvé. Par
exemple, le bloc suivant définit une gestion spécifique des erreurs d’étendue et
un autre gestionnaire pour toutes les autres erreurs de calcul entier :
try
{ instructions effectuant des opérations de calcul entier }
except
on ERangeError do { gestion des calculs hors étendue };
on EIntError do { gestion des autres erreurs de calcul entier };
end;
Par contre, si le gestionnaire de EIntError est placé avant le gestionnaire de
ERangeError, l’exécution n’atteint jamais le gestionnaire spécifique à ERangeError.
Redéclenchement de l’exception
Parfois, quand vous gérez localement une exception, vous voulez juste étendre la
gestion définie par le bloc conteneur et pas la remplacer. Mais, bien entendu,
quand votre gestionnaire local en a fini avec l’exception, il détruit
automatiquement l’instance d’exception et le gestionnaire du bloc conteneur ne
peut donc pas agir dessus. Vous pouvez néanmoins empêcher le gestionnaire de
détruire l’exception, ce qui laisse au gestionnaire du conteneur l’opportunité d’y
répondre.
Exemple Quand une exception se produit, vous voulez afficher un message à l’utilisateur,
puis laisser faire la gestion standard. Pour ce faire, déclarez un gestionnaire local
de l’exception qui affiche le message puis utilise le mot réservé raise. C’est ce
que l’on appelle redéclencher l’exception, comme le montre le code suivant :
try
{ instructions }
try
{ instructions spéciales }
except
on ESomething do
begin
{ gestions des instructions spéciales }
raise;{ redéclenche l’exception }
end;
end;
except
on ESomething do ...;{ gestion à effectuer dans tous les cas }
end;
Utilisation de TApplication.HandleException
HandleException propose une gestion par défaut des exceptions au niveau de
l’application. Si une exception passe au travers de tous les blocs try du code de
l’application, l’application appelle automatiquement la méthode HandleException
qui affiche une boîte de dialogue indiquant qu’une erreur a eu lieu. Vous pouvez
utiliser HandleException de la manière suivante :
try
{ instructions }
except
Application.HandleException(Self);
end;
Pour toutes les exceptions sauf EAbort, HandleException appelle, s’il existe, le
gestionnaire d’événement OnException. Si vous voulez à la fois gérer l’exception
et proposer, comme la VCL, ce comportement par défaut, ajoutez un appel de
HandleException à votre code :
try
{ instructions spéciales }
except
on ESomething do
begin
{ ne gère que les instructions spéciales }
Application.HandleException(Self);{ appelle HandleException }
end;
end;
Pour plus d’informations, recherchez routines de gestion des exceptions dans l’index
de l’aide.
Exceptions silencieuses
Les applications Delphi gèrent la plupart des exceptions qui ne sont pas gérées
spécifiquement dans votre code en affichant une boîte de message qui affiche la
chaîne de message de l’objet exception. Vous pouvez également définir des
exceptions “silencieuses” pour lesquelles, par défaut l’application n’affiche pas le
message d’erreur.
Les exceptions silencieuses sont utiles quand vous ne voulez pas gérer une
exception mais simplement abandonner l’opération. L’abandon d’une opération
est semblable à l’utilisation des procédures Break et Exit pour sortir d’un bloc,
mais elle permet de sortir de plusieurs niveaux de blocs imbriqués.
Les exceptions silencieuses descendent toutes du type d’exception standard
EAbort. Le gestionnaire d’exception par défaut des applications VCL Delphi
affiche la boîte de dialogue de message d’erreur pour toutes les exceptions qu’il
reçoit sauf pour celles qui dérivent de EAbort.
Remarque Dans les applications console, la boîte de dialogue d’erreur est affichée même
pour une exception EAbort.
Création d’interfaces
Une interface est semblable à une classe ne contenant que des méthodes
abstraites et une définition claire de ses fonctionnalités. Strictement parlant, les
définitions des méthodes d’interface spécifient le nombre et le type de leurs
paramètres, le type renvoyé et le comportement prévu. Les méthodes d’une
interface sont reliées, sémantiquement ou logiquement, pour indiquer le rôle de
begin
for I := Low(Painters) to High(Painters) do
Painters[I].Paint;
end;
procedure RotateObjects(Degrees: Integer; Rotaters: array of IRotate);
var
I: Integer;
begin
for I := Low(Rotaters) to High(Rotaters) do
Rotaters[I].Rotate(Degrees);
end;
RotateObjects n’a pas besoin que les objets sachent se dessiner par eux-mêmes et
PaintObjects n’exige pas que les objets sachent comment pivoter. Cela permet aux
objets définis précédemment d’être utilisés plus fréquemment que s’ils n’avaient
été écrits que pour la classe TFigure.
Pour des détails sur la syntaxe, la définition du langage et les règles s’appliquant
aux interfaces, voir dans le Guide du langage Pascal Objet, la section Interfaces
d’objet.
Implémentation de IUnknown
Toutes les interfaces dérivent, directement ou non, de l’interface IUnknown. Cette
interface définit les fonctionnalités essentielles d’une interface, c’est-à-dire
l’interrogation dynamique et la gestion de la durée de vie. Ces fonctionnalités
sont mises en place par les trois méthodes de IUnknown :
• QueryInterface est une méthode d’interrogation dynamique d’un objet donné
qui obtient les références des interfaces gérées par l’objet.
• AddRef est une méthode de comptage de références qui incrémente le
compteur à chaque appel réussi de QueryInterface. Tant que le compteur de
référence est non nul, l’objet doit rester en mémoire.
• Release est utilisée en conjonction avec AddRef pour permettre à un objet de
connaître sa durée de vie et de déterminer s’il peut se supprimer lui-même.
Quand le compteur de références atteint zéro, l’implémentation de l’interface
libère les objets sous-jacents.
Chaque classe qui implémente des interfaces doit implémenter les trois méthodes
de IUnknown, les autres méthodes déclarées dans toutes ses interfaces ancêtre,
ainsi que toutes les méthodes déclarées dans l’interface même. Néanmoins, vous
pouvez hériter de l’implémentation des méthodes d’interface déclarées dans
votre classe.
TInterfacedObject
La VCL définit une classe simple, TInterfacedObject qui, pratiquement, sert de
classe de base car elle implémente les méthodes de IUnknown. La classe
TInterfacedObject est déclarée de la manière suivante dans l’unité System :
type
TInterfacedObject = class(TObject, IUnknown)
private
FRefCount: Integer;
protected
function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
property RefCount: Integer read FRefCount;
end;
Dériver directement de TInterfacedObject est trivial. Dans l’exemple de déclaration
suivant, TDerived est un descendant direct de TInterfacedObject qui implémente
une interface hypothétique, IPaint :
type
TDerived = class(TInterfacedObject, IPaint)
...
end;
Comme TInterfacedObject implémente les méthodes de IUnknown, elle gère
automatiquement le comptage de références et la gestion mémoire pour les objets
interfacés. Pour davantage d’informations, voir “Gestion mémoire des objets
interface” à la page 3-22 qui traite également de l’écriture de classes
implémentant des interfaces sans utiliser le mécanisme de comptage de
références inhérent à TInterfacedObject.
Utilisation de l’opérateur as
Les classes implémentant des interfaces peuvent utiliser l’opérateur as pour se
lier dynamiquement à l’interface. Dans l’exemple suivant :
procedure PaintObjects(P: TInterfacedObject)
var
X: IPaint;
begin
X := P as IPaint;
{ instructions }
end;
la variable P, de type TInterfacedObject, peut être affectée à la variable X qui est
une référence à l’interface IPaint. La liaison dynamique rend cette affectation
possible. Le compilateur génère pour cette affectation le code appelant la
méthode QueryInterface de l’interface IUnknown de P ; le compilateur ne peut
savoir à partir du type déclaré de P si l’instance de P gère réellement IPaint. A
l’exécution, soit P se résoud en une référence à une interface IPaint, soit une
exception est déclenchée. Dans l’un ou l’autre cas, l’affectation de P à X ne
génère pas une erreur à la compilation comme se serait le cas si P avait pour
type une classe n’implémentant pas IUnknown.
Quand vous utilisez l’opérateur as pour une liaison dynamique avec une
interface, vous devez respecter les règles suivantes :
• Déclaration explicite de IUnknown : même si toutes les interfaces dérivent de
IUnknown, il ne suffit pas qu’une classe implémente les méthodes de
IUnknown pour pouvoir utiliser l’opérateur as. Cela reste vrai même si la classe
implémente également les interfaces qu’elle déclare explicitement. La classe
doit déclarer explicitement IUnknown dans sa liste d’ancêtres.
• Utilisation d’un IID : les interfaces peuvent utiliser un identificateur basé sur
un identificateur global unique (GUID). Les GUID utilisés pour identifier des
interfaces sont appelés des identificateurs d’interface (IID). Si vous utilisez
l’opérateur as avec une interface, elle doit avoir un IID associé. Pour créer un
nouveau GUID dans votre code source, vous pouvez utiliser le raccourci
Ctrl+Shift+G de l’éditeur de code.
Agrégation
L’agrégation propose une approche modulaire de la réutilisation de code via des
sous-objets définissant les fonctionnalités d’un objet conteneur tout en lui cachant
les détails de l’implémentation. Dans l’agrégation, un objet externe implémente
une ou plusieurs interfaces. La seule exigence est qu’il implémente IUnknown.
L’objet interne (il peut y en avoir plusieurs) peut implémenter une ou plusieurs
interfaces, mais seul l’objet externe expose les interfaces. Cela vaut pour les
interfaces qu’il implémente et pour celles implémentées par les objets qu’il
contient. Les clients ne savent rien des objets internes. C’est l’objet externe qui
donne accès aux interfaces de l’objet interne, leur implémentation étant
totalement transparente. Cependant la classe objet externe peut échanger le type
de classe de l’objet interne avec toute classe qui implémente la même interface.
Réciproquement, le code des classes d’objet interne peut être partagé avec les
autres classes souhaitant l’utiliser.
Le modèle d’implémentation de l’agrégation définit des règles explicites pour
l’implémentation de IUnknown en utilisant la délégation. L’objet interne doit
implémenter une interface IUnknown sur lui-même qui contrôle le comptage de
références pour l’objet interne. Cette implémentation de IUnknown surveille la
relation entre les objets interne et externe. Par exemple, quand un objet de son
type (l’objet interne) est créé, la création réussit uniquement pour une interface
demandée de type IUnknown. L’objet interne implémente également une
deuxième interface IUnknown pour toutes les interfaces qu’il implémente. Ces
sont les interfaces exposées par l’objet externe. Ce deuxième IUnknown délègue
tous les appels de QueryInterface, AddRef et Release à l’objet externe.
Reportez-vous à la documentation en ligne Microsoft pour connaître les règles
s’appliquant lors de la création d’une agrégation. Quand vous écrivez vos
propres classes d’agrégation, vous pouvez également consulter les détails de
l’implémentation de IUnknown dans TComObject. TComObject est une classe COM
qui gère l’agrégation. Si vous écrivez des applications COM, vous pouvez
également utiliser directement TComObject comme classe de base.
Types caractère
Delphi a trois types caractère : Char, AnsiChar et WideChar.
Le type caractère Char provient du Pascal standard, il a été utilisé dans Turbo
Pascal puis en Pascal Objet. Plus tard, le Pascal Objet a ajouté les types AnsiChar
et WideChar comme des types caractère spécifiques utilisés pour gérer les
représentations standard des caractères dans le système d’exploitation Windows.
AnsiChar a été ajouté pour gérer le jeu de caractères ANSI sur 8 bits et WideChar
pour gérer le jeu de caractères 16 bits Unicode. Les caractères de type WideChar
sont également appelés caractères étendus. Les caractères étendus sont codés sur
deux octets afin que le jeu de caractères puisse représenter davantage de
caractères différents. Quand AnsiChar et WideChar ont été implémentés, Char est
devenu le type caractère par défaut représentant l’implémentation dont
l’utilisation est conseillée pour un système donné. Si vous utilisez Char dans une
application, n’oubliez pas que son implémentation est susceptible de changer des
versions ultérieures de Delphi.
Le tableau suivant décrit brièvement ces types caractère :
Pour davantage d’informations sur l’utilisation de ces types caractère, voir dans
l’aide en ligne du Guide du langage Pascal Objet la rubrique Types caractère
Pour davantage d’informations sur les caractères Unicode, voir dans l’aide en
ligne du Guide du langage Pascal Objet la rubrique A propos des jeux de
caractères étendus
Types chaîne
Delphi propose trois catégories de types que vous pouvez utiliser pour
manipuler des chaînes : les pointeurs de caractère, les types chaîne et les classes
chaîne VCL. Cette section présente les types chaîne et décrit leur utilisation avec
les pointeurs de caractère. Pour des informations sur les classes chaîne VCL, voir
dans l’aide en ligne la rubrique TStrings.
Delphi dispose aujourd’hui de trois implémentations de chaîne : les chaînes
courtes, les chaînes longues et les chaînes étendues. Il existe plusieurs types
chaîne qui représentent ces implémentations. De plus, le mot réservé string
correspond par défaut à l’implémentation de chaîne actuellement recommandée.
Chaînes courtes
String a été le premier type chaîne utilisé en Turbo Pascal. String était à
l’origine implémenté avec une chaîne courte. Les chaînes courtes allouent entre 1
et 256 octets : le premier octet contenant la longueur de la chaîne, les octets
restants contenant les caractères de la chaîne :
S: string [0..n]// le type string original
Quand les chaînes longues ont été implémentées, string a été modifié pour
exploiter par défaut une implémentation de chaîne longue et ShortString a été
introduit comme type permettant la compatibilité ascendante. ShortString est un
type prédéfini pour une chaîne de longueur maximum :
S: string [255]// Le type ShortString
La quantité de mémoire allouée pour un ShortString est statique, c’est-à-dire
qu’elle est déterminée à la compilation. Par contre, l’emplacement de la mémoire
d’un ShortString peut être allouée dynamiquement (par exemple si vous utilisez
un PShortString qui est un pointeur sur un ShortString). Le nombre d’octets de
stockage employés par une variable de type chaîne courte correspond à la
longueur maximum du type chaîne courte plus un. Pour le type prédéfini
ShortString, la taille est donc de 256 octets.
Les chaînes courtes, déclarées en utilisant la syntaxe string[0..n] et le type
prédéfini ShortString existent essentiellement pour proposer une compatibilité
ascendante avec les versions précédentes de Delphi et de Borland Pascal.
Une directive de compilation, $H, détermine si le mot réservé string correspond
à une chaîne longue ou courte. A l’état par défaut, {$H+}, string représente une
chaîne longue. Vous pouvez le changer en un ShortString en utilisant la directive
{$H-}. L’état {$H-} est surtout pratique pour utiliser du code écrit pour des
versions précédentes du Pascal Objet qui utilisaient par défaut le type chaîne
courte. Toutefois, les chaînes courtes peuvent s’avérer utiles dans des structures
de données quand vous avez besoin de composants de taille fixe ou dans des
DLL si vous ne souhaitez pas utiliser l’unité ShareMem (voir aussi dans l’aide en
ligne Gestion de la mémoire). Vous pouvez redéfinir localement la signification
des définitions de type chaîne pour générer des chaînes courtes. Vous pouvez
aussi changer les déclarations de chaînes courtes en string[255] ou en ShortString
qui sont dépourvues d’ambiguïtés et indépendantes de la directive $H.
Pour davantage d’informations sur les chaînes et le type ShortString, voir dans
l’aide en ligne du Guide du langage Pascal Objet la rubrique Chaînes courtes
Chaînes longues
Les chaînes longues sont des chaînes allouées dynamiquement dont la longueur
maximum est limitée uniquement par la mémoire disponible. Comme les chaînes
courtes, les chaînes longues utilisent des caractères ANSI sur 8 bits et un
indicateur de longueur. A la différence des chaînes courtes, les chaînes longues
n’ont pas un élément zéro contenant la longueur dynamique de la chaîne. Pour
connaître la longueur d’une chaîne longue, vous devez utiliser la fonction
standard Length et pour spécifier sa longueur vous devez utiliser la procédure
standard SetLength. Les chaînes longues utilisent le comptage de références et,
comme les PChars, ce sont des chaînes à zéro terminal. Pour davantage
d’informations sur l’implémentation des chaînes longues, voir dans l’aide en
ligne du Guide du langage Pascal Objet la rubrique Chaînes longues
Les chaînes longues sont désignées par le mot réservé string et par
l’identificateur prédéfini AnsiString. Dans les nouvelles applications, il est
conseillé d’utiliser le type chaîne longue. Tous les composants de la VCL sont
compilés de cette manière, généralement en utilisant string. Si vous écrivez des
composants, ils doivent également utiliser des chaînes longues tout comme doit
le faire le code recevant des données provenant de propriétés VCL de type
chaîne. Si vous voulez écrire du code spécifique qui utilise systématiquement
une chaîne longue, vous devez utiliser AnsiString. Si vous voulez écrire du code
flexible qui vous permet de changer facilement le type quand une nouvelle
implémentation de chaîne deviendra la norme, vous devez alors utiliser string.
Chaînes étendues
Le type WideChar permet de représenter des chaînes de caractères étendus comme
des tableaux de WideChars. Les chaînes étendues sont des chaînes composées de
caractères Unicode sur 16 bits. Comme les chaînes longues, les chaînes étendues
sont allouées dynamiquement et leur longueur maximum n’est limitée que par la
quantité de mémoire disponible. Par contre, les chaînes étendues n’utilisent pas le
comptage de références. La mémoire allouée dynamiquement pour la chaîne est
libérée quand la chaîne étendue sort de portée. Pour tout le reste, les chaînes
étendues ont les mêmes attributs que les chaînes longues. Le type chaîne étendu
est désigné par l’identificateur prédéfini WideString.
Comme la version 32 bits de OLE utilise Unicode, toutes les chaînes doivent être
de type chaîne étendu dans les propriétés et paramètres de méthodes OLE
Automation. De plus, la plupart des fonctions de l’API OLE utilisent des chaînes
étendues à zéro terminal.
Pour davantage d’informations sur les chaînes étendues, voir dans l’aide en ligne
du Guide du langage Pascal Objet la rubrique Chaînes étendues
Types PChar
Un PChar est un pointeur sur une chaîne à zéro terminal de caractères de type
Char. Chacun des trois types caractère dispose d’un type de pointeur prédéfini :
• Un PChar est un pointeur sur une chaîne à zéro terminal de caractères 8 bits.
• Un PAnsiChar est un pointeur sur une chaîne à zéro terminal de caractères 8 bits.
• Un PWideChar est un pointeur sur une chaîne à zéro terminal de caractères
16 bits.
PChar est, avec les chaînes courtes, l’un des types chaîne qui existaient à l’origine
dans le Pascal Objet. Il a été conçu à l’origine pour assurer la compatibilité avec
les types du langage C et de l’API Windows.
Chaînes ouvertes
Le type OpenString est obsolète mais vous pouvez le rencontrer dans du code
ancien. Il n’existe que pour la compatibilité 16 bits et n’est autorisé que dans les
paramètres. OpenString était utilisé, avant l’implémentation des chaînes longues,
pour permettre le transfert comme paramètre d’une chaîne courte de taille
indéterminée. Par exemple, la déclaration suivante :
procedure a(v : openstring);
permet de transmettre comme paramètre une chaîne de longueur quelconque. En
son absence, la longueur de chaîne des paramètres formel et réel doivent
correspondre exactement. Vous n’avez pas besoin d’utiliser OpenString dans les
nouvelles applications que vous écrivez.
Pour d’autres informations sur la directive de compilation {$P+/-} voir
“Directives de compilation portant sur les chaînes” à la page 35 de ce chapitre.
L’utilisation d’un schéma de codage avec des caractères étendus présente cet
avantage que vous pouvez avoir sur les chaînes des présupposés qui ne sont pas
valables dans les systèmes MBCS. Il y a en effet une relation directe entre le
nombre d’octets de la chaîne et son nombre de caractères. Il n’y a pas le risque,
comme avec les jeux de caractères MBCS, de couper un caractère en deux ou de
confondre le deuxième octet d’un caractère avec le début d’un autre caractère.
Par contre, les caractères étendus présentent un inconvénient : Windows 95 ne
gère pas l’appel des fonctions de l’API avec des caractères étendus. C’est pour
cela que tous les composants VCL représentent toutes les valeurs chaîne comme
des chaînes sur un octet ou des chaînes sur plusieurs octets (MBCS). Effectuer la
conversion entre le système de caractères étendu et le système MBCS à chaque
fois que vous lisez ou écrivez une propriété chaîne exigerait une quantité
phénoménale de code supplémentaire et ralentirait vos applications. Par contre,
vous pouvez traduire une propriété chaîne en caractères étendus quand vous
voulez mettre en oeuvre des algorithmes de manipulation de chaînes particuliers
qui exploitent la correspondance 1:1 entre les caractères et WideChars.
Gestion des jeux de caractères multi-octets (MBCS) : les MBCS sont utilisés pour
écrire du code pour les localisations extrême-orientales. Les caractères multi-octets
sont représentés par un mélange de codes de caractère sur un ou deux octets, le
nombre d’octets ne correspond donc pas systématiquement à la longueur de la
chaîne. Les routines qui gèrent les MBCS analysent les caractères sur un ou deux
octets. ByteType et StrByteType déterminent si un octet donné est l’octet de tête
d’un caractère sur deux octets. Faites attention en manipulant des caractères
multi-octets à ne pas tronquer une chaîne en coupant en deux un caractère sur
deux octets. Ne transmettez pas de caractères comme paramètre d’une fonction
ou d’une procédure puisque la taille d’un caractère ne peut être déterminée à
l’avance. Il faut, à la place, transmettre un pointeur sur un caractère ou une
chaîne. Pour davantage d’informations sur MBCS, voir “Codage de l’application”
à la page 2 du chapitre 10, “Création d’applications internationales.”.
Les routines utilisées pour les noms de fichier sous forme de chaîne :
AnsiCompareFileName, AnsiLowerCaseFileName et AnsiUpperCaseFileName utilisent
toutes la localisation Windows. Vous devez toujours utiliser des noms de fichier
totalement portables car la localisation (le jeu de caractères) utilisée pour les
noms de fichier peut changer selon l’interface utilisateur par défaut.
Dépendances de chaîne
Il est parfois nécessaire de convertir des chaînes longues en chaînes à zéro
terminal, par exemple si vous utilisez une fonction qui attend un PChar.
Cependant, comme les chaînes longues utilisent le comptage de références, le
transtypage d’une chaîne en un PChar augmente de un les dépendances de la
chaîne sans augmenter également le compteur de références. Quand le compteur
de références atteint zéro, la chaîne est détruite même s’il y a encore des
dépendances portant dessus. Le transtypage en PChar disparaît également, et ce
alors même que la routine à laquelle vous l’avez transmis l’utilise peut-être
encore. Si vous transtypez une chaîne en un PChar, c’est vous qui êtes
responsable de la durée de vie du PChar résultant. Par exemple :
procedure my_func(x: string);
begin
// faire quelque chose avec x
some_proc(PChar(x)); // transtype la chaîne en PChar
// vous devez maintenant garantir que la chaîne existe
// tant que la procédure some_proc a besoin de l’utiliser
end;
begin
i := GetModuleFilename(0, @buf, SizeOf(buf));// traite @buf comme un PChar
S := buf;
// instructions
end;
Cette manière de procéder est envisageable si la taille du tampon reste
suffisamment petite pour être allouée sur la pile. Elle est également fiable car la
conversion est automatique entre un type array of char et un type string. A la
fin de l’exécution de GetModuleFilename, la longueur de la chaîne indique
correctement le nombre d’octets écrits dans buf.
Pour éliminer le surcoût de la copie du tampon, il est possible de transtyper la
chaîne en un PChar (si vous êtes certain que la routine n’a pas besoin que le PChar
reste en mémoire). Mais dans ce cas, la synchronisation de la longueur de la
chaîne n’est pas effectuée automatiquement comme c’est le cas lors de l’affectation
de array of char vers string. Vous devez réinitialiser la longueur de la chaîne afin
de refléter la longueur réelle de la chaîne. Si vous utilisez une fonction qui renvoie
le nombre d’octets copiés, une seule ligne de code suffit à le faire :
var
S: string;
begin
SetLength(S, 100);// avant de transtyper en PChar, vérifiez que la chaîne n’est pas vide
SetLength(S, GetModuleFilename( 0, PChar(S), Length(S) ) );
// instructions
end;
Manipulation de fichiers
Plusieurs opérations courantes portant sur les fichiers sont prédéfinies dans la
bibliothèque d’exécution Pascal Objet. Les procédures et fonctions manipulant les
fichiers agissent à un niveau élevé. Pour la plupart des routines, il vous suffit de
spécifier le nom du fichier et la routine fait pour vous les appels nécessaires au
système d’exploitation. Dans certains cas, vous utiliserez à la place des handles de
fichier. Le Pascal Objet propose des routines pour la plupart des manipulations de
fichier. Quand ce n’est pas le cas, d’autres routines sont décrites.
gestion de fichier Delphi, comme AssignPrn ou writeln, les utilisent. Ces types
fichier sont obsolètes et sont incompatibles avec les handles de fichier Windows.
Si vous avez besoin de travailler avec ces types de fichier anciens, consultez le
Guide du langage Pascal Objet .
Handles de fichier Windows : les handles de fichier Pascal Objet encapsulent le
type de handle de fichier Windows. Les routines de manipulation de fichier de
la bibliothèque d’exécution qui utilisent des handles de fichier Windows
encapsulent généralement des fonctions de l’API Windows. Ainsi, FileRead
appelle la fonction Windows ReadFile. Comme les fonctions Delphi utilisent la
syntaxe Pascal Objet et peuvent spécifier la valeur par défaut de paramètres,
elles peuvent servir commodément d’interface avec l’API Windows. L’utilisation
de ces routines est évidente et, si vous êtes à l’aise avec les routines de fichier de
l’API Windows, vous pouvez les utiliser pour manipuler les E/S de fichier.
Flux fichier : les flux fichier sont des instances d’objet de la classe TFileStream de
la VCL utilisées pour accéder aux informations de fichiers disque. Les flux fichier
sont portables et proposent une approche de haut niveau des opérations d’E/S
de fichier. TFileStream a une propriété Handle qui vous donne accès au handle de
fichier Windows. La section suivante décrit TFileStream.
Le paramètre Mode spécifie comment le fichier doit être ouvert à la création du flux
fichier. Le paramètre Mode est constitué d’un mode d’ouverture et d’un mode de
partage reliés par un ou logique. Le mode d’ouverture doit prendre l’une des valeurs
suivantes :
Valeur Signification
fmCreate TFileStream crée un fichier portant le nom spécifié. S’il existe déjà un
fichier portant ce nom, il est ouvert en mode écriture.
fmOpenRead Ouvre le fichier en lecture seulement.
fmOpenWrite Ouvre le fichier en écriture seulement. L’écriture dans le fichier
remplace son contenu actuel.
fmOpenReadWrite Ouvre le fichier pour en modifier le contenu et non pour le remplacer.
Valeur Signification
fmShareCompat Le partage est compatible avec la manière d’ouvrir les FCB.
fmShareExclusive En aucun cas, les autres applications ne peuvent ouvrir le fichier.
fmShareDenyWrite Les autres applications peuvent ouvrir le fichier en lecture, mais pas en
écriture.
fmShareDenyRead Les autres applications peuvent ouvrir le fichier en écriture, mais pas en
lecture.
fmShareDenyNone Rien n’empêche les autres applications de lire ou d’écrire dans le fichier.
Les constantes d’ouverture et de partage de fichier sont définies dans l’unité SysUtils.
Read est une fonction qui lit jusqu’à Count octets dans le fichier associé à un flux
fichier en commençant à la position en cours (Position) et les place dans Buffer.
Read déplace ensuite la position en cours dans le fichier du nombre d’octets
effectivement lus. Read a le prototype suivant :
function Read(var Buffer; Count: Longint): Longint; override ;
Read est utile quand le nombre d’octets du fichier est inconnu. Read renvoie le
nombre d’octets effectivement transférés qui peut être inférieur à Count si le
marqueur de fin de fichier a été atteint.
Write est une fonction qui écrit Count octets de Buffer dans le fichier associé au
flux fichier en commençant à la position en cours (Position). Write a le prototype
suivant :
function Write(const Buffer; Count: Longint): Longint; override ;
Après avoir écrit dans le fichier, Write avance la position en cours dans le fichier
du nombre d’octets écrits et renvoie le nombre d’octets effectivement écrits qui
peut être inférieur à Count si la fin du tampon a été atteinte.
La paire de procédures correspondantes ReadBuffer et WriteBuffer ne renvoient
pas comme Read et Write le nombre d’octets lus ou écrits. Ces procédures sont
utiles dans les situations où le nombre d’octet est connu et obligatoire : par
exemple pour la lecture de structures. ReadBuffer et WriteBuffer déclenchent une
exception en cas d’erreur (EReadError et EWriteError), alors que les méthodes
Read et Write ne le font pas. Les prototypes de ReadBuffer et WriteBuffer sont :
procedure ReadBuffer(var Buffer; Count: Longint);
procedure WriteBuffer(const Buffer; Count: Longint);
Ces méthodes appellent les méthodes Read et Write pour réaliser la lecture ou
l’écriture.
begin
fs := TFileStream.Create('Temp.txt', fmCreate or fmOpenWrite);
fs.Write(s, Length(s));// cela donne un résultat faux
fs.Write(PChar(s)^, Length(s));// Cela donne le bon résultat
end;
Valeur Signification
soFromBeginning Offset part du début de la ressource. Seek place à la position Offset. Offset doit
être >= 0.
soFromCurrent Offset part de la position en cours dans la ressource. Seek place à la position
Position + Offset.
soFromEnd Offset part de la fin de la ressource. Offset doit être <= 0 afin d’indiquer le
nombre d’octets avant la fin du fichier.
Copie
CopyFrom copie le nombre spécifié d’octets d’un flux (fichier) dans un autre.
function CopyFrom(Source: TStream; Count: Longint): Longint;
L’utilisation de CopyFrom évite à l’utilisateur qui veut copier des données de
créer un tampon, d’y placer les données, de les écrire puis de libérer le tampon.
CopyFrom copie Count octets de Source dans le flux. CopyFrom déplace ensuite la
position en cours de Count octets et renvoie le nombre d’octets copiés. Si Count vaut
0, CopyFrom initialise la position dans Source à 0 avant de lire puis de copier dans le
flux la totalité des données de Source. Si Count est supérieur ou inférieur à 0,
CopyFrom lit à partir de la position en cours dans Source.
Création d’applications,
Chapter 4
4
de composants
et de bibliothèques
Ce chapitre donne un aperçu de la manière d’utiliser Delphi pour créer des
applications, des bibliothèques et des composants.
Création d’applications
L’utilisation principale de Delphi est la conception et la génération d’applications
Windows. Il y a trois types de base d’application Windows :
• Les applications d’interface utilisateur graphique Windows
• Les applications console
• Les applications service
Applications Windows
Quand vous compilez un projet, un fichier exécutable (.EXE) est créé.
Généralement, l’exécutable fournit les fonctions de base de votre programme et
les programmes simples sont souvent composés uniquement d’un EXE. Vous
pouvez aussi étendre une application en appelant des DLL, des paquets ou
d’autres bibliothèques complétant un exécutable.
Windows offre deux modèles d’interface utilisateur d’application :
• L’interface de document unique (abrégé en anglais par SDI)
• L’interface de document multiple (abrégé en anglais par MDI)
Applications SDI
Pour créer une nouvelle application SDI :
1 Sélectionnez Fichier|Nouveau pour afficher la boîte de dialogue Nouveaux
éléments.
2 Cliquez sur l’onglet Projets et sélectionnez Application SDI.
3 Choisissez OK.
Par défaut, la propriété FormStyle de l’objet Form a la valeur fsNormal, Delphi
suppose que toute nouvelle application est une application SDI.
Applications MDI
Pour créer une nouvelle application MDI :
1 Sélectionnez Fichier|Nouveau pour afficher la boîte de dialogue Nouveaux
éléments.
2 Cliquez sur l’onglet Projets et sélectionnez Application MDI.
3 Choisissez OK.
Les applications MDI nécessitent plus de réflexion et sont plus complexes à
concevoir que les applications SDI. Les applications MDI contiennent des fenêtres
enfant qui se trouvent dans la fenêtre client ; la fiche principale contient des
fiches enfant. Affectez la propriété FormStyle de l’objet TForm pour spécifier si la
fiche est un enfant (fsMDIForm) ou si c’est la fiche principale (fsMDIChild). Pour
éviter d’avoir à redéfinir à plusieurs reprises les propriétés des fenêtres enfant,
vous avez intérêt à définir une classe de base pour les fiches enfant et à dériver
chaque fiche enfant de cette classe.
Modèles de programmation
Les modèles de programmation sont des structures communément appelées
"squelettes" que vous pouvez ajouter au code source puis remplir. Par exemple,
si vous voulez utiliser une boucle for dans votre code, vous pouvez insérer le
modèle suivant :
for := to do
begin
end;
Pour insérer un modèle de code dans l’éditeur de code, appuyez sur Ctrl-j et
sélectionnez le modèle que vous voulez utiliser. Vous pouvez également ajouter
vos propres modèles à cette collection. Pour ajouter un modèle :
1 Sélectionnez Outils|Options d’environnement.
2 Choisissez l’onglet Audit de code.
3 Dans la section Modèles, choisissez Ajouter.
4 Saisissez un nom court et entrez une description brève du nouveau modèle.
5 Spécifiez le modèle de code dans la boîte de saisie Code.
6 Choisissez OK.
Applications console
Les applications console sont des programmes 32 bits exécutés sans interface
graphique, généralement dans une fenêtre console. Habituellement, ces
applications ne nécessitent pas une saisie utilisateur importante et exécutent un
jeu limité de fonctions.
Pour créer une nouvelle application console, choisissez Fichier|Nouveau et
sélectionnez Expert console dans la boîte de dialogue Nouveaux éléments.
Applications service
Les applications service reçoivent les requêtes des applications client, traitent ces
requêtes et renvoient les informations aux applications client. Habituellement,
elles s'exécutent en arrière-plan, sans nécessiter de saisie utilisateur importante.
Un serveur Web, FTP ou de messagerie électronique est un exemple
d'application service.
Pour créer une application qui implémente un service Win32, choisissez Fichier|
Nouveau puis sélectionnez Application service dans la boîte de dialogue
Nouveaux éléments. Cela ajoute à votre projet une variable globale appelée
Application de type TServiceApplication.
Une fois une application service créée, une fenêtre apparaît dans le concepteur
qui correspond à un service (TService). Implémentez le service en initialisant ses
propriétés et ses gestionnaires d’événements dans l’inspecteur d’objets. Vous
pouvez ajouter des services supplémentaires en choisissant Service dans la boîte
de dialogue Nouveaux éléments. N’ajoutez pas de services à une application qui
n’est pas une application service. En effet, même si un objet TService est ajouté,
l’application ne génère pas les événements nécessaires, ni ne fait les appels
Windows appropriés au service.
Une fois que votre application service est construite, vous pouvez installer ses
services avec le SCM (Service Control Manager). Les autres applications peuvent
alors lancer vos services en envoyant des requêtes au SCM.
Pour installer les services de votre application, exécutez-la à l'aide de l'option
/INSTALL. L'application installe ses services puis quitte, en affichant un message
de confirmation si les services sont correctement installés. Vous pouvez
supprimer l’affichage du message de confirmation en exécutant l'application
service à l'aide de l'option /SILENT.
Pour désinstaller les services, exécutez-la depuis la ligne de commande à l'aide
de l'option /UNINTALL (vous pouvez aussi utiliser l'option /SILENT pour
supprimer l'affichage du message de confirmation lors de la désinstallation).
Exemple Le service suivant contient un TServerSocket dont le port est initialisé à 80. C’est
le port par défaut des navigateurs Web pour envoyer des requêtes à des
serveurs Web et celui utilisé par les serveurs Web pour répondre aux
navigateurs Web. Cet exemple spécifique produit, dans le répertoire C:\Temp,
un document texte appelé WebLogxxx.log (où xxx correspond au ThreadID). Il
ne doit y avoir qu’un seul serveur surveillant un port donné, donc si vous
utilisez déjà un serveur Web, vous devez vous assurer qu’il n’est pas à l’écoute
(le service doit être arrêté).
Pour voir les résultats, ouvrez un navigateur Web sur la machine locale. Pour
l’adresse, entrez “localhost” (sans les guillemets). Eventuellement, le navigateur
va faire une erreur de dépassement de délai mais vous devez obtenir un fichier
appelé weblogxxx.log dans le répertoire C:\temp.
1 Pour créer l’exemple, choisissez Fichier|Nouveau et sélectionnez Application
Service dans la boîte de dialogue Nouveaux éléments. Une fenêtre nommée
Service1 apparaît. Ajoutez un composant ServerSocket de la page Internet de
la palette de composants à la fenêtre service (Service1).
2 Ajoutez ensuite une donnée membre de type TMemoryStream à la classe
TService1. La section interface de l’unité doit ressembler à :
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
ScktComp;
type
TService1 = class(TService)
ServerSocket1: TServerSocket;
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure Service1Execute(Sender: TService);
private
{ déclarations privées }
Stream: TMemoryStream; // Ajoutez cette ligne
public
function GetServiceController: PServiceController; override ;
{ déclarations publiques }
end;
var
Service1: TService1;
3 Sélectionnez ensuite ServerSocket1, le composant ajouté à l’étape 1. Dans
l’inspecteur d’objets, double-cliquez sur l’événement OnClientRead et ajoutez
le gestionnaire d’événement suivant :
procedure TService1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Buffer: PChar;
begin
Buffer := nil;
while Socket.ReceiveLength > 0 do begin
try
Buffer := AllocMem(Socket.ReceiveLength);
Socket.ReceiveBuf(Buffer^, Socket.ReceiveLength);
Stream.Write(Buffer^, StrLen(Buffer));
finally
FreeMem(Buffer);
end;
Stream.Seek(0, soFromBeginning);
Stream.SaveToFile('c:\Temp\Weblog' + IntToStr(ServiceThread.ThreadID) + '.log');
end;
end;
4 Sélectionnez enfin Service1 en cliquant sur la zone client de la fenêtre (mais
pas sur le composant ServiceSocket). Dans l’inspecteur d’objets, double-cliquez
sur l’événement OnExecute et ajoutez le gestionnaire d’événement suivant :
procedure TService1.Service1Execute(Sender: TService);
begin
Stream := TMemoryStream.Create;
try
ServerSocket1.Port := 80; // port WWW
ServerSocket1.Active := True;
while not Terminated do begin
ServiceThread.ProcessRequests(False);
end;
ServerSocket1.Active := False;
finally
Stream.Free;
end;
end;
Quand vous écrivez votre application service, vous devez tenir compte des
éléments suivants :
• Threads de service
• Propriétés de nom d’un service
• Débogage des services
Threads de service
Chaque service dispose de son propre thread (TServiceThread), donc si votre
application service implémente plusieurs services, vous devez vous assurer que
l’implémentation de vos services est compatible avec l’utilisation de threads. La
classe TServiceThread est ainsi conçue de façon à implémenter le service dans le
gestionnaire d’événement OnExecute de TService. Le thread du service dispose de
sa propre méthode Execute qui contient une boucle appelant les gestionnaires
OnStart et OnExecute du service avant de traiter de nouvelles requêtes. Comme le
traitement des requêtes de service peut prendre longtemps et l’application
service peut recevoir simultanément plusieurs requêtes d’un ou de plusieurs
clients, il est plus efficace de lancer un nouveau thread (dérivé de TThread et non
de TServiceThread) pour chaque requête et de déplacer l’implémentation du
service dans la méthode Execute du nouveau thread. Cela permet à la boucle
Execute du thread du service de traiter continuellement de nouvelles requêtes
sans avoir à attendre la fin du gestionnaire OnExecute du service. Cette manière
de procéder est illustrée par l’exemple suivant :
Exemple Ce service sonne tous les 500 millisecondes depuis le thread standard. Il gère la
pause, la reprise et l’arrêt du thread quand on indique au service de se
suspendre, de reprendre ou de s’arrêter.
1 Choisissez Fichier|Nouveau et sélectionnez Application Service dans la boîte
de de dialogue Nouveaux éléments. Une fenêtre nommée Service1 apparaît.
2 Dans la section interface de votre unité, déclarez un nouveau descendant de
TThread nommé TSparkyThread. C’est le thread qui réalise le travail pour le
service. Il doit être déclaré comme suit :
TSparkyThread = class(TThread)
public
procedure Execute; override ;
end;
3 Ensuite, dans la section implementation de l’unité, créez une variable globale
pour une instance de TSparkyThread :
var
SparkyThread: TSparkyThread;
COM et DCOM
Delphi contient des classes et des experts qui simplifient la création des éléments
essentiels d’une application COM, OLE ou ActiveX. L’utilisation de Delphi pour
créer des applications basées sur COM offre de nombreuses possibilités, allant de
l’amélioration de la conception de logiciel en utilisant des interfaces de manière
interne dans une application, à la création d’objets qui peuvent interagir avec
d’autres objets utilisant l’API COM du système, comme les extensions du shell
Win95 ou la gestion multimedia DirectX.
Pour davantage d’informations sur COM et les contrôles ActiveX, voir
chapitre 44, “Présentation des technologies COM”, chapitre 48, “Création d’un
contrôle ActiveX” et “Distribution d’une application client en tant que contrôle
ActiveX” à la page 14-33.
Pour davantage d’informations sur DCOM, voir “Utilisation de connexions
DCOM” à la page 14-10.
MTS
Le serveur de transaction Microsoft (MTS) est une extension de COM qui met à
la disposition des applications distribuées COM, des services de transaction, la
sécurité et la mise en commun des ressources.
Pour davantage d’informations sur MTS, voir chapitre 50, “Création des objets
MTS” et “Utilisation de MTS” à la page 14-6.
Conception de l’interface
Chapter 5
5
utilisateur des applications
Delphi vous permet de créer une interface utilisateur en sélectionnant des
composants de la palette des composants et en les déposant dans des fiches.
Liaison de fiches
L’ajout d’une fiche au projet ajoute au fichier projet une référence à cette fiche
mais pas aux autres unités du projet. Avant d’écrire du code faisant référence à
la nouvelle fiche, vous devez ajouter une référence à cette fiche dans les fichiers
unité des fiches y faisant référence. Cela s’appelle la liaison de fiche.
La liaison de fiche est fréquemment utilisée pour donner accès aux composants
contenus dans une autre fiche. Par exemple, la liaison de fiche est souvent
employée pour permettre à une fiche contenant des composants orientés données
de se connecter aux composants d’accès aux données d’un module de données.
Pour lier une fiche à une autre fiche :
1 Sélectionnez la fiche qui fait référence à une autre.
2 Choisissez Fichier|Utiliser unité.
3 Sélectionnez le nom de l’unité de la fiche qui doit être référencée.
4 Choisissez OK.
Lier une fiche à une autre signifie simplement que les clauses uses de l’unité
d’une fiche contient une référence àl’unité de l’autre fiche. Ainsi la fiche liée et
ses composants rentrent dans la portée de la fiche.
Manipulation de l’application
La variable globale Application de type TApplication se trouve dans chaque
application Windows Delphi. Application encapsule l’application et propose de
nombreux services fonctionnant en arrière-plan du programme. Ainsi, Application
gère la manière d’appeler un fichier d’aide depuis les menus de votre
programme. La compréhension du fonctionnement de TApplication est plus
importante pour le concepteur de composants que pour le développeur
d’applications autonomes, mais vous devez définir les options gérées par
Application dans la page Application de la boîte de dialogue Options de projet
(Projet|Options) quand vous créez un projet.
De plus, Application reçoit de nombreux événements qui s’appliquent à
l’application dans son ensemble. Par exemple, l’événement OnActivate vous
permet de réaliser des actions au démarrage de l’application, l’événement OnIdle
vous permet d’exécuter des traitements en arrière-plan lorsque l’application n’est
pas occupée, l’événement OnMessage vous permet d’intercepter les messages
Windows, etc. Bien que vous ne puissiez pas utiliser l’EDI pour examiner les
propriétés et les événements de la variable globale Application, un autre
composant, TApplicationEvents, intercepte les événements et vous permet de
fournir les gestionnaires d’événements à l’aide de l’EDI.
Gestion de l’écran
Une variable globale de type TScreen, appelée Screen, est créée lors de la création
d’un projet. Screen encapsule l’état de l’écran dans lequel l’application s’exécute.
Parmi les fonctions imparties à Screen, il y a la gestion de l’aspect du curseur, la
taille de la fenêtre dans laquelle s’exécute l’application, la liste des fontes
disponibles pour le périphérique écran et d’autres comportements de l’écran. Si
votre application s’exécute sur plusieurs moniteurs, Screen gère une liste des
moniteurs et leurs dimensions afin que vous puissiez effectivement gérer la
disposition de l’interface utilisateur.
Gestion de la disposition
A son niveau le plus élémentaire, vous contrôlez l’organisation de votre interface
utilisateur par la manière de disposer les contrôles dans les fiches. Le choix des
emplacements est reflété par les propriétés Top, Left, Width et Height des
contrôles. Vous pouvez modifier ces valeurs à l’exécution afin de modifier la
position ou la taille des contrôles dans les fiches.
Les contrôles disposent de nombreuses autres propriétés qui leur permettent de
s’adapter automatiquement à leur contenu ou à leur conteneur. Cela vous permet
d’organiser les fiches de telle manière que les différents éléments forment un
tout unifié.
être activé à la réception du message. Si vous avez juste cliqué dans la fiche,
l’application peut ne pas tenir compte du message.
Le type enregistrement transmis par Windows à l’application est appelé un
TMsg. Windows prédéfinit une constante pour chaque message, ces valeurs sont
stockées dans le champ de message de l’enregistrement TMsg. Chacune de ces
constantes commence par les lettres “wm”.
La VCL gère automatiquement les messages sauf si vous surchargez le système
de gestion des messages et créez vos propres gestionnaires d’événements. Pour
davantage d’informations sur les messages et la gestion des messages, voir
“Compréhension du système de gestion des messages” à la page 37-1,
“Modification de la gestion des messages” à la page 37-3 et “Création de
nouveaux gestionnaires de messages” à la page 37-5.
Toutes les fiches créées de cette manière dans l’unité du projet apparaissent
quand le programme est exécuté et restent en mémoire durant toute l’exécution
de l’application.
Bien entendu, vous ne pouvez pas utiliser de variables locales pour les fiches
non modales dans les gestionnaires d’événements car elles doivent avoir une
portée globale pour garantir que la fiche existe aussi longtemps qu’elle est
utilisée. Show rend la main dès que la fiche est ouverte, donc si vous utilisez une
variable locale, la variable locale sort de portée immédiatement.
private
FColor: Pointer;
public
constructor CreateWithColor(Value: Pointer; Owner: TComponent);
end;
La fiche contient une boîte liste nommée ColorListBox contenant une liste de
noms de couleur. Quand il est choisi, le bouton nommé SelectButton mémorise le
nom de la couleur sélectionnée dans ColorListBox puis ferme la fiche.
CancelButton est un bouton qui ferme simplement la fiche.
Remarquez l’ajout à la déclaration de la classe d’un constructeur défini par
l’utilisateur qui attend un argument Pointer. Ce paramètre Pointer pointe sur une
chaîne gérée par la fiche qui déclenche ColorForm. Ce constructeur a
l’implémentation suivante :
constructor TColorForm(Value: Pointer; Owner: TComponent);
begin
FColor := Value;
String(FColor^) := '';
end;
Le constructeur enregistre le pointeur dans une donnée membre privée FColor et
initialise la chaîne avec une chaîne vide.
Remarque Pour utiliser ce constructeur défini par l’utilisateur, la fiche doit être créée
explicitement. Ce ne peut pas être une fiche auto-créée au démarrage de
l’application. Pour davantage d’informations, voir “Contrôle du stockage en
mémoire des fiches” à la page 5-5.
Dans l’application, l’utilisateur sélectionne une couleur dans la boîte liste puis
clique sur le bouton SelectButton pour enregistrer son choix et fermer la fiche. Le
gestionnaire d’événement OnClick du bouton SelectButton doit avoir la forme
suivante :
procedure TColorForm.SelectButtonClick(Sender: TObject);
begin
with ColorListBox do
if ItemIndex >= 0 then
String(FColor^) := ColorListBox.Items[ItemIndex];
end;
Close;
end;
Remarquez comment le gestionnaire d’événement stocke le nom de couleur
sélectionné dans la chaîne référencée par le pointeur qui a été transmise au
constructeur.
Pratiquement, pour utiliser ColorForm, la fiche appelante doit transmettre au
constructeur un pointeur sur une chaîne existante. Supposons par exemple que
ColorForm est instanciée par une fiche appelée ResultsForm en réponse au choix
d’un bouton de ResultsForm nommé UpdateButton. Le gestionnaire d’événement
de ce bouton doit avoir la forme suivante :
procedure TResultsForm.UpdateButtonClick(Sender: TObject);
var
MainColor: String;
begin
GetColor(Addr(MainColor));
if MainColor <> '' then
{faire quelque chose avec la chaîne MainColor}
else
{faire autre chose car aucune couleur n’a été sélectionnée}
end;
Pour des informations sur la façon de lier un élément de menu à du code qui
s’exécute lorsque l’élément est sélectionné, voir “Association d’événements de menu
à des gestionnaires d’événements” à la page 2-30.
Conception de menus
Vous devez ajouter un composant menu à vos fiches pour chaque menu devant
apparaître dans l’application. Vous pouvez créer chaque structure de menu à
partir de zéro ou partir de l’un des modèles de menu prédéfinis.
Cette section décrit les principes de base de la création de menus à la
conception. Pour davantage d’informations sur les modèles de menu, voir
“Utilisation des modèles de menu” à la page 5-27.
Comme pour le composant menu, Delphi ajoute le nom des éléments de menu à
la déclaration de type de la fiche et leur nom apparaît dans la liste des
composants.
Création de sous-menus
La plupart des menus d’application contiennent des listes déroulantes qui
apparaissent à côté d’un élément de menu afin de proposer des commandes
associées supplémentaires. De telles listes sont signalées par un pointeur à droite
de l’élément de menu. Delphi gère les niveaux de sous-menus sans aucune
limitation dans l’imbrication.
Une telle organisation de votre structure de menu permet d’économiser de la
place verticalement. Néanmoins, pour optimiser la conception, il est préférable de
ne pas utiliser plus de deux ou trois niveaux de menus dans la conception de
votre interface. Dans le cas des menus surgissants, il est préférable de n’utiliser
au maximum qu’un niveau de sous-menu.
Figure 5.6 Structure de menus imbriqués
Elément de
menu de la barre
Elément de menu
d’une liste de
Elément de menu
imbriqué
Affichage du menu
Vous pouvez voir votre menu dans la fiche à la conception sans exécuter le code
de votre programme. Les composants menu surgissant sont visibles dans la fiche
à la conception, mais pas le menu surgissant lui-même. Utilisez le concepteur de
menus pour visualiser un menu surgissant à la conception.
Pour visualiser le menu :
1 Si la fiche n’est pas visible, cliquez dans la fiche ou dans le menu Voir,
choisissez la fiche que vous voulez voir.
2 Si la fiche contient plusieurs menus, sélectionnez le menu à visualiser dans la
liste déroulante de la propriété Menu de la fiche.
Le menu apparaît dans la fiche exactement tel qu’il apparaîtra à l’exécution du
programme.
Cette boîte de dialogue énumère tous les menus associés à la fiche dont les
menus sont ouverts dans le concepteur de menus.
2 Dans la liste de la boîte de dialogue Sélection de menu, choisissez le menu
que vous voulez voir ou modifier.
Pour utiliser l’inspecteur d’objets afin de passer d’un menu de la fiche à un
autre :
1 Sélectionnez la fiche dont vous voulez choisir un menu.
2 Dans la liste des composants, sélectionnez le menu que vous voulez modifier.
3 Dans la page Propriétés de l’inspecteur d’objets, sélectionnez la propriété Items
de ce menu, puis cliquez sur le bouton points de suspension ou double-
cliquez sur [Menu].
2 Sélectionnez le modèle de menu que vous voulez insérer, puis appuyez sur
Entrée ou choisissez OK.
Cela insère le menu dans votre fiche à la position courante du curseur. Si, par
exemple, le curseur est positionné sur un élément de menu d’une liste, le
modèle de menu est inséré en dessous de l’élément sélectionné. Si le curseur
est dans la barre de menu, le modèle de menu est inséré à gauche du curseur.
Fusion de menus
Dans les applications MDI, comme l’application exemple éditeur de texte ou
dans les applications client OLE, le menu principal de votre application doit être
capable d’intégrer les éléments de menu d’une autre fiche ou d’un objet serveur
OLE. Ce processus s’appelle la fusion de menus.
Pour préparer des menus à la fusion, vous devez spécifier les valeurs de deux
propriétés :
• Menu, une propriété de la fiche.
• GroupIndex, une propriété des éléments du menu.
• Pour insérer des éléments sans remplacer des éléments du menu principal,
laissez des intervalles numériques entre les éléments du menu principal et
intercalez les numéros de la fiche enfant.
Vous pouvez par exemple, numéroter les éléments du menu principal 0 et 5,
et insérer les éléments du menu enfant en les numérotant 1, 2, 3 et 4.
Les turboboutons sont conçus pour fonctionner dans des volets barre d’outils.
Généralement, un turbobouton n’a pas d’intitulé mais seulement une petite
image (appelée un glyphe) qui représente la fonction du bouton.
Les turboboutons ont trois modes de fonctionnement. Ils peuvent :
• Se comporter comme des boutons poussoir normaux.
• Se comporter comme une bascule
• Se comporter comme un ensemble de boutons radio.
Pour implémenter des turboboutons dans des barres d’outils, vous pouvez :
• Ajouter un turbobouton dans un volet barre d’outils
• Affecter un glyphe au turbobouton
• Définir l’état initial du turbobouton
• Créer un groupe de turboboutons
• Utiliser des boutons bascules
Si, par exemple, votre application propose un outil de dessin activé par défaut,
vérifiez que le bouton correspondant de la barre d’outils est enfoncé au
démarrage de l’application. Pour ce faire, affectez une valeur non nulle à sa
propriété GroupIndex et la valeur True à sa propriété Down.
Objets action
Les actions sont des commandes utilisateur portant sur des objets cible. Les
actions sont créées dans l’éditeur de composant liste d’actions. Ces actions sont
ultérieurement connectées à des contrôles client via leur liaison d’action. Le
mécanisme action/liste d’actions fait intervenir les composants suivants :
• Une action (TAction) est l’implémentation d’une action (par exemple, copier le
texte sélectionné) dans une cible (par exemple, un contrôle de saisie). Une
action est déclenchée par un client en réponse à une commande de
l’utilisateur (c’est-à-dire un clic de la souris). Les clients sont habituellement
des éléments de menu ou des boutons. L’unité StdActns contient des classes,
dérivées de TAction, qui implémentent les commandes de menu (les actions)
standard d’édition et de manipulation des fenêtres qui apparaissent dans la
plupart des applications Windows.
• Une liste d’actions (TActionList) est un composant qui gère une liste d’actions
(TAction). Les listes d’actions servent à la conception d’interfaces utilisateur
permettant de manipuler des actions.
• Une liaison d’action (TActionLink) est un objet qui gère la connexion entre les
actions et les clients. Les liaisons d’actions déterminent si une action, et
laquelle, est actuellement applicable à un client donné.
Deux autres unités, StdActns et DBActns, contiennent des classes auxiliaires qui
implémentent des actions spécifiques courantes de Windows et des ensembles de
données. Pour davantage d’informations, voir “Classes d’actions prédéfinies” à la
page 5-44. La plupart des contrôles de la VCL proposent des propriétés (c’est-à-
dire Action) et des méthodes (c’est-à-dire ExecuteAction) qui permettent de les
utiliser comme client ou comme cible d’actions.
Centralisation du code
De nombreux contrôles, par exemple TToolButton, TSpeedButton, TMenuItem ou
TButton ont une propriété publiée nommée Action. Quand vous affectez à la
propriété Action l’une des actions de votre liste d’actions, les valeurs des
propriétés correspondantes de l’action sont copiées dans celles du contrôle.
Toutes les propriétés et événements en commun avec l’objet action (sauf Name et
Tag) sont liées dynamiquement au contrôle. Ainsi, par exemple, au lieu de
dupliquer le code désactivant des boutons et des éléments de menu, vous
pouvez centraliser ce code dans un objet action : quand l’action est désactivée,
tous les boutons et les éléments de menu correspondants sont désactivés.
Liaison de propriétés
La liaison d’action du client est le mécanisme par lequel ses propriétés sont
associées (liées) aux propriétés d’une action. Quand une action change, la liaison
d’action est responsable de l’actualisation des propriétés du client. Pour
davantage d’informations sur les propriétés gérées par une classe donnée de
liaison d’action, voir les diverses classes de liaison d’action dans l’aide en ligne
de la VCL.
Vous pouvez surcharger de manière sélective les valeurs des propriétés
contrôlées par un objet action associé en initialisant la valeur de la propriété
dans le composant ou le contrôle client. Cela ne modifie pas la valeur de la
propriété dans l’action et seul le client est affecté.
Exécution d’actions
Quand un composant ou un contrôle client est cliqué, l’événement OnExecute se
produit pour son action associée. Par exemple, le code suivant est le gestionnaire
d’événement OnExecute pour une action qui inverse la visibilité d’une barre
d’outils quand une action est exécutée :
procedure TForm1.Action1Execute(Sender: TObject);
begin
{ Inverse la visibilité de Toolbar1 }
ToolBar1.Visible := not ToolBar1.Visible;
end;
Remarque Si vous utilisez un bouton outil ou un élément de menu, vous devez initialiser
manuellement la propriété Images de la barre d’outils ou du menu correspondant
avec la propriété Images de la liste d’actions. Cela reste vrai même si la propriété
ImageIndex est liée dynamiquement au client.
Pour des informations générales sur les événements et les gestionnaires
d’événements, voir “Utilisation des événements et des gestionnaires
d’événements” à la page 2-28.
La figure suivante illustre la séquence de répartition du cycle d’exécution d’une
action nommée Cut1. Ce diagramme part de la relation illustrée par la
figure 5.10, ce qui signifie que le client Speedbutton1 est lié à l’action Cut1 via sa
liaison d’action. La propriété Action de Speedbutton1 a donc la valeur Cut1. En
conséquence, la méthode Click de Speedbutton1 appelle la méthode Execute de
Cut1.
Figure 5.11 Cycle d’exécution d’une action
Remarque Dans la description de cette séquence, l’appel d’une méthode par une autre ne
signifie pas nécessairement que l’appel apparaît explicitement dans le code de la
méthode.
Cliquer sur Speedbutton1 démarre le cycle d’exécution suivant :
• La méthode Click de Speedbutton1 appelle Cut1.Execute.
• L’action Cut1 s’en remet à sa liste d’actions (ActionList1) pour le traitement de
son Execute. Elle le fait en appelant la méthode ExecuteAction de la liste
d’actions en se transmettant elle-même comme paramètre.
• ActionList1 appelle son gestionnaire d’événement (OnExecuteAction) pour
ExecuteAction (la méthode ExecuteAction d’une liste d’actions s’applique à
toutes les actions contenues dans la liste). Ce gestionnaire a un paramètre
Handled qui renvoie False par défaut. Si le gestionnaire est défini et gère
l’événement, il doit renvoyer True et la séquence de traitement s’arrête là.
Par exemple :
procedure TForm1.ActionList1ExecuteAction(Action: TBasicAction; var Handled: Boolean);
begin
{ Empêche l’exécution des actions contenues par ActionList1 }
Handled := True;
end;
Si l’exécution n’est pas gérée à ce point dans le gestionnaire de la liste d’actions,
le traitement se poursuit :
• L’action Cut1 est redirigée vers la méthode ExecuteAction de l’objet Application,
qui appelle le gestionnaire OnExecuteAction (la méthode ExecuteAction de
l’application s’applique à toutes les actions de cette application). La séquence
est la même que pour le ExecuteAction de la liste d’actions : le gestionnaire a
un paramètre Handled qui renvoie False par défaut. Si le gestionnaire est défini
et gère l’événement, il doit renvoyer True et la séquence de traitement s’arrête
ici. Par exemple :
procedure TForm1.ApplicationExecuteAction(Action: TBasicAction; var Handled: Boolean);
begin
{ Empêche l’exécution de toutes les actions de Application }
Handled := True;
end;
Si l’exécution n’est pas gérée par le gestionnaire d’événement de l’application,
alors Cut1 envoie le message CM_ACTIONEXECUTE à la méthode WndProc de
l’application en se transmettant elle-même comme paramètre. L’application tente
alors de trouver une cible sur laquelle exécuter l’action (voir la figure 5.12,
“Cibles des actions”).
Les classes d’actions prédéfinies décrites plus haut, mais aussi les classes
d’actions que vous créez utilisent cette séquence d’exécution :
Figure 5.12 Cibles des actions
• Si Form1 n’est pas une cible appropriée, elle appelle ExecuteAction pour chacun
des contrôles visibles dont elle est propriétaire jusqu’à trouver une cible.
Remarque Si l’action impliquée est de type TCustomAction, l’action est automatiquement
désactivée quand l’action n’est pas gérée si sa propriété DisableIfNoHandler a la
valeur True.
Recensement d’actions
Vous pouvez recenser ou annuler le recensement de vos propres actions dans
l’EDI en utilisant les routines globales de l’unité ActnList :
procedure RegisterActions(const CategoryName: string; const AClasses: array of
TBasicActionClass; Resource: TComponentClass);
procedure UnRegisterActions(const AClasses: array of TBasicActionClass);
Utilisez ces routines de la même manière que RegisterComponents s’utilise pour
recenser des composants. Par exemple, le code suivant recense dans l’EDI les
actions :
{ recensement des actions standard }
RegisterActions('', [TAction], nil);
RegisterActions('Edit', [TEditCut, TEditCopy, TEditPaste], TStandardActions);
RegisterActions('Window', [TWindowClose, TWindowCascade, TWindowTileHorizontal,
TWindowTileVertical, TWindowMinimizeAll, TWindowArrange], TStandardActions);
Programmes exemple
Pour des exemples de programmes utilisant les actions et les listes d’actions, voir
Demos\RichEdit. De plus, les démos de l’expert Application (Fichier|page
Nouveau projet), MDI Application, SDI Application et Win95 Logo Application
peuvent utiliser les objets action et liste d’actions.
Trois événements permettent aux sites d’influer sur l'empilement des contrôles
enfant :
property OnGetSiteInfo: TGetSiteInfoEvent;
TGetSiteInfoEvent = procedure (Sender: TObject; DockClient: TControl; var InfluenceRect:
TRect; var CanDock: Boolean) of object;
OnGetSiteInfo intervient sur le site d'empilement lorsque l'utilisateur fait glisser
un enfant empilable sur le contrôle. Il permet au site d'indiquer s'il accepte en
tant qu’enfant le contrôle spécifié par le paramètre DockClient et, si tel est le cas,
où l'enfant doit se trouver en vue de son empilement. Lorsque OnGetSiteInfo
intervient, InfluenceRect est initialisée selon les coordonnées d'écran du site
d'empilement et CanDock est intialisée à True. Une région d'empilement plus
limitée peut être créée en changeant InfluenceRect et l'enfant peut être rejeté en
mettant CanDock à False.
property OnDockOver: TDockOverEvent;
TDockOverEvent = procedure (Sender: TObject; Source: TDragDockObject; X, Y: Integer; State:
TDragState; var Accept: Boolean) of object;
OnDockOver intervient sur le site d'empilement lorsque l'utilisateur fait glisser un
enfant empilable sur le contrôle. Il est analogue à l'événement OnDragOver au
cours d'une opération normale de glisser-déposer. Utilisez-le pour indiquer que
l'enfant peut être relâché en vue de son empilement, en initialisant la propriété
Accept. Si le contrôle empilable est rejeté par le gestionnaire d'événement
OnGetSiteInfo (par exemple, si le type de contrôle est incorrect), OnDockOver ne
se produit pas.
property OnDockDrop: TDockDropEvent;
TDockDropEvent = procedure (Sender: TObject; Source: TDragDockObject; X, Y: Integer) of
object;
OnDockDrop intervient sur le site d'empilement lorsque l'utilisateur relâche
l'enfant empilable sur le contrôle. Il est analogue à l'événement OnDragDrop au
cours d'une opération normale de glisser-déposer. Utilisez-le pour faire en sorte
d'accepter le contrôle en tant que contrôle enfant. L'accès au contrôle enfant peut
être obtenu à l'aide de la propriété Control de TDockObject spécifié par le
paramètre Source.
Les composants mémo ou éditeur de texte formaté ne gèrent pas les barres de
défilement exactement de la même manière. Le composant éditeur de texte
formaté peut dissimuler ses barres de défilement si le texte ne sort pas des
limites du composant. Le composant Mémo affiche toujours les barres de
défilement lorsqu’elles ont été activées.
Sélection de texte
Pour transférer du texte dans le Presse-papiers, il faut d’abord sélectionner ce
texte. La possibilité de mettre en surbrillance le texte sélectionné est intégrée aux
composants éditeur. Lorsque l’utilisateur sélectionne un texte, celui-ci apparaît en
surbrillance.
Le tableau suivant dresse la liste des propriétés fréquemment utilisées pour la
manipulation du texte sélectionné.
Pour les boîtes liste et les boîtes à options, il y a plusieurs styles dessinés par le
propriétaire, appelés fixed et variable, comme décrit dans le tableau suivant. Les
grilles dessinées par le propriétaire sont toujours “fixes” : bien que la taille des
lignes et des colonnes soit variable, la taille des cellules est fixée avant le dessin
de la grille.
L’exemple suivant montre comment ajouter des images à une liste de chaînes. Ce
code est extrait d’une application de gestion de fichiers dans laquelle chaque
lecteur correct est représenté par une lettre et est associé à un bitmap indiquant
le type du lecteur. L’événement OnCreate se présente comme suit :
procedure TFMForm.FormCreate(Sender: TObject);
var
Drive: Char;
AddedIndex: Integer;
begin
for Drive := 'A' to 'Z' do { passe par tous les lecteurs possibles }
begin
case GetDriveType(Drive +':/') of { valeurs positives signifiant des lecteurs valides }
DRIVE_REMOVABLE: { ajoute un onglet }
AddedIndex := DriveTabSet.Tabs.AddObject(Drive, Floppy.Picture.Graphic);
DRIVE_FIXED: { ajoute un onglet }
AddedIndex := DriveTabSet.Tabs.AddObject(Drive, Fixed.Picture.Graphic);
DRIVE_REMOTE: { ajoute un onglet }
AddedIndex := DriveTabSet.Tabs.AddObject(Drive, Network.Picture.Graphic);
end;
if UpCase(Drive) = UpCase(DirectoryOutline.Drive) then { lecteur actif ? }
DriveTabSet.TabIndex := AddedIndex; { puis en fait l’onglet en cours }
end;
end;
Rafraîchissement de l’écran
A certains moments, Windows détermine que l’apparence de certains objets
affichés à l’écran doit être rafraîchie. Il génère donc des messages WM_PAINT,
que la VCL redirige vers des gestionnaires d’événements OnPaint. Lorsque vous
utilisez la méthode Refresh, la VCL appelle n’importe quel gestionnaire
d’événement OnPaint ayant été écrit pour cet objet. Par défaut, Delphi nomme ce
gestionnaire d’événement FormPaint. La méthode Refresh est parfois utilisée pour
rafraîchir un composant sur une fiche. Par exemple, la méthode Refresh peut être
appelée dans le gestionnaire d’événement OnResize de la fiche afin de réafficher
des graphiques ou pour dessiner un fond sur la fiche.
Bien que certains systèmes d’exploitation gèrent automatiquement l’affichage des
zones clientes d’une fenêtre qui ne sont plus valides, Windows ne le fait pas.
Pour Windows, tout dessin est considéré comme permanent. Lorsqu’une fiche ou
un contrôle est temporairement masqué, par exemple lors d’un glisser-déplacer,
la fiche ou le contrôle doivent repeindre la zone masquée lorsqu’elle ne l’est
plus. Pour plus d’informations sur le message WM_PAINT, voir l’aide en ligne
de Windows.
Lors de l’utilisation du contrôle TImage, la VCL gère automatiquement le dessin
et le rafraîchissement du graphique contenu dans le TImage. Dessiner sur un
TImage crée une image persistante. Par conséquent, il n’est pas nécessaire de
redessiner l’image contenue. Au contraire, le canevas d’un TPaintBox écrit
directement sur le pilote de l’écran, et de ce fait, tout ce qui est dessiné sur le
canevas du PaintBox est transitoire. Cela est vrai pour les contrôles similaires, y
compris la fiche elle-même. De plus, si vous dessinez ou peignez à partir du
constructeur d’un TPaintBox, vous devrez ajouter ce code dans le gestionnaire
OnPaint afin que l’image soit repeinte à chaque fois que la zone cliente est
invalidée.
Pour davantage d’informations sur ces propriétés, voir “Utilisation des propriétés
de l’objet canevas” à la page 7-5.
Le tableau suivant liste les différentes méthodes pouvant être utilisées :
Pour davantage d’informations sur ces méthodes, voir “Utilisation des méthodes
du canevas pour dessiner des objets graphiques” à la page 7-10.
Les valeurs de ces propriétés déterminent la façon dont le crayon change les pixels
de la ligne. Par défaut, chaque crayon est noir, a une largeur de 1 pixel, est de style
uni, et a un mode appelé copie qui écrase tout ce qui se trouve déjà sur le canevas.
Dessin de lignes
Pour dessiner une ligne droite sur un canevas, utilisez la méthode LineTo du
canevas.
La méthode LineTo dessine une ligne partant de la position en cours du crayon et
allant au point spécifié, et fait du point d’arrivée de la ligne la position en cours. Le
canevas dessine la ligne en utilisant son crayon.
Par exemple, la méthode suivante dessine des lignes diagonales qui se croisent sur
une fiche, chaque fois que la fiche est peinte :
procedure TForm1.FormPaint(Sender: TObject);
begin
with Canvas do
begin
MoveTo(0, 0);
LineTo(ClientWidth, ClientHeight);
MoveTo(0, ClientHeight);
LineTo(ClientWidth, 0);
end;
end;
Dessin de polylignes
En plus des lignes individuelles, le canevas peut dessiner des polylignes, qui
sont des groupes composés d’un nombre quelconque de segments de ligne reliés
entre eux.
Pour dessiner une polyligne sur un canevas, appelez la méthode PolyLine du canevas.
Le paramètre passé à la méthode PolyLine est un tableau de points. Imaginez
qu’une polyligne réalise une méthode MoveTo sur le premier point et une méthode
LineTo sur chaque point successif. Si vous voulez dessiner plusieurs lignes, vous
devez savoir que Polyline est plus rapide que la méthode MoveTo et que la
méthode LineTo, car elle élimine un certain nombre d’appels supplémentaires.
Dessin de formes
Les canevas disposent de méthodes vous permettant de dessiner différents types
de formes. Le canevas dessine le pourtour d’une forme avec son crayon, puis
remplit l’intérieur avec son pinceau. La ligne qui définit la bordure de la forme
est déterminée par l’objet Pen en cours.
Cette section couvre :
• Dessin de rectangle et d’ellipses
• Dessin de rectangles à coins arrondis
• Dessin de polygones
Dessin de polygones
Pour dessiner, sur un canevas, un polygone ayant un nombre quelconque de côtés,
appelez la méthode Polygon du canevas.
Polygon prend un tableau de points comme seul paramètre et relie les points avec le
crayon, puis relie le dernier point au premier de façon à fermer le polygone. Après
avoir dessiné les lignes, Polygon utilise le pinceau pour remplir la zone interne au
polygone.
Le code suivant dessine un triangle rectangle dans la moitié inférieure gauche de la
fiche :
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.Polygon([Point(0, 0), Point(0, ClientHeight),
Point(ClientWidth, ClientHeight)]);
end;
Un type énuméré est juste un moyen rapide pour affecter des valeurs
séquentielles à des constantes. Depuis qu'il s'agit aussi d'une déclaration de type,
vous pouvez utiliser la vérification de type du Pascal Objet pour vous assurer
que vous n'affectez que ces valeurs spécifiques.
Pour déclarer un type énuméré, utilisez le mot réservé type, suivi par un
identificateur de type, du signe égal et des identificateurs pour les valeurs mis
entre parenthèses et séparés par des virgules.
Par exemple, le code suivant déclare un type énuméré pour tous les outils de
dessin de l’application graphique :
type
TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);
Par convention, les identificateurs de type commencent par la lettre T, et les
constantes similaires (celles constituant le type énuméré) commencent par un même
préfixe de deux caractères (comme ici dt pour “drawing tool”).
La déclaration du type TDrawingTool est équivalente à la déclaration d'un
groupe de constantes :
const
dtLine = 0;
dtRectangle = 1;
dtEllipse = 2;
dtRoundRect = 3;
La principale différence est qu'en déclarant un type énuméré, vous affectez des
constantes et pas seulement des valeurs, mais aussi un type qui permet d'utiliser
la vérification de type du Pascal Objet pour vous prémunir de nombreuses
erreurs. Une variable de type TDrawingTool peut être affectée seulement par une
des constantes dtLine..dtRoundRect. Toute tentative d'affectation d'un autre
nombre (même de la portée 0..3) génèrera une erreur de compilation.
Dans le code suivant, un champ ajouté à une fiche fera le suivi de l’outil de
dessin de la fiche :
type
TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);
TForm1 = class(TForm)
...{ déclarations de méthode}
public
Drawing: Boolean;
Origin, MovePt: TPoint;
DrawingTool: TDrawingTool;{ champ pour l’outil en cours }
end;
Positionnement du contrôle
Un contrôle image peut être placé n'importe où dans une fiche. Pour tirer le
meilleur parti de la capacité d’un contrôle image à ajuster sa taille sur celle de son
image, le seul point à définir est le coin supérieur gauche du contrôle. Si le contrôle
image sert d'emplacement non visible pour un bitmap, il peut être placé n'importe
où dans la fiche, comme un composant non visuel.
Si vous placez le contrôle image en le mettant à l’intérieur de la boîte de
défilement déjà installée dans la zone client de la fiche, vous serez sûr que la boîte
de défilement affichera des barres de défilement pour permettre l’accès aux parties
du dessin n’apparaissant pas à l’écran. Définissez ensuite les propriétés du contrôle
image.
Remplacement de l’image
Il est possible à tout moment de remplacer l’image d’un contrôle image. Si un
nouveau graphique est affecté à l’image ayant déjà un graphique, le nouveau
graphique remplace l’ancien.
Pour remplacer l’image contenue dans un contrôle image, affectez un nouveau
graphique à l’objet Picture du contrôle image.
La création d’un nouveau graphique passe par le même processus que la création
du premier graphique (voir la section “Définition de la taille initiale du bitmap” à
la page 7-18), mais il faut également permettre à l’utilisateur de choisir une taille
différente de celle utilisée par défaut pour le graphique initial. Un moyen simple de
proposer une telle option est de présenter une boîte de dialogue comme celle de la
figure 7.1.
Figure 7.1 Boîte de dialogue Dimension bitmap de l’unité BMPDlg.
WidthEdit
HeightEdit
Cette boîte de dialogue particulière est créée dans l’unité BMPDlg incluse dans le
projet GraphEx (répertoire EXAMPLES\DOC\GRAPHEX).
Cette boîte de dialogue étant dans votre projet, ajoutez-la à la clause uses de
l’unité de votre fiche principale. Vous pouvez ensuite attacher un gestionnaire à
l’événement OnClick de l’élément de menu Fichier | Nouveau. Voici un exemple :
procedure TForm1.New1Click(Sender: TObject);
var
Bitmap: TBitmap;{ variable temporaire pour le nouveau bitmap }
begin
with NewBMPForm do
begin
ActiveControl := WidthEdit;{ focalisation sur le champ largeur }
WidthEdit.Text := IntToStr(Image.Picture.Graphic.Width);{ dimensions en cours... }
HeightEdit.Text := IntToStr(Image.Picture.Graphic.Height);{ ...par défaut }
if ShowModal <> idCancel then{ continuer si l’utilisateur n’annule pas la boîte de
dialogue }
begin
Bitmap := TBitmap.Create;{ créer un objet bitmap }
Bitmap.Width := StrToInt(WidthEdit.Text);{ utiliser la largeur spécifiée }
Bitmap.Height := StrToInt(HeightEdit.Text);{ utiliser la hauteur spécifiée }
Image.Picture.Graphic := Bitmap;{ remplacer le graphique par le nouveau bitmap }
CurrentFile := '';{ indique le fichier non nommé }
end;
end;
end;
Remarque L’affectation d’un nouveau bitmap à la propriété Graphic de l’objet Picture oblige
l’objet Picture à détruire le bitmap existant et à devenir propriétaire du nouveau. La
VCL gère automatiquement les détails de la libération des ressources associées à
l’ancien bitmap.
Répondre à la souris
Votre application peut répondre aux actions de la souris : enfoncement du
bouton de la souris, déplacement de la souris et relâchement du bouton de la
souris. Elle peut aussi répondre à un clic (un appui suivi d’un relâchement, sans
déplacer la souris) qui peut être généré par certaines frappes de touches (comme
l’appui sur la touche Entrée dans une boîte de dialogue modale).
Cette section traite des sujets suivants :
• Qu’y a-t’il dans un événement de souris ?
• Réponse à l’action bouton de souris enfoncé
• Réponse à l’action bouton de souris relâché
• Réponse au déplacement de la souris
Le code suivant affiche la chaîne 'Ici!' sur une fiche à l’emplacement du clic de la
souris :
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.TextOut(X, Y, 'Ici!');{ écrire du texte aux coordonnées (X, Y) }
end;
Lorsque l’application est exécutée, le curseur étant sur la fiche, tout appui sur le
bouton de la souris fera apparaître la chaîne "Ici!" au point cliqué. Ce code
définit la position de dessin en cours par les coordonnées du point où l’utilisateur
a enfoncé le bouton de la souris :
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.MoveTo(X, Y);{ définir la position du crayon }
end;
Désormais, l’enfoncement du bouton de la souris définit la position du crayon et
initialise ainsi le point de départ de la ligne. Pour dessiner une ligne jusqu’au point
où l’utilisateur a relâché le bouton, vous devez répondre à l’événement bouton de
souris relâché.
public
Drawing: Boolean;
Origin, MovePt: TPoint;{ champs pour stocker les points }
end;
Nous disposons maintenant d’un champ Drawing permettant de déterminer s’il faut
dessiner. Il faut donc l’initialiser à True lorsque l’utilisateur enfonce le bouton de la
souris et à False lorsqu’il le relâche :
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Drawing := True;{ définir l’indicateur de dessin }
Canvas.MoveTo(X, Y);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Canvas.LineTo(X, Y);
Drawing := False;{ effacer l’indicateur de dessin }
end;
Ensuite, vous pouvez modifier le gestionnaire de l’événement OnMouseMove de
façon à ne dessiner que si Drawing est à True :
procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Drawing then{ dessiner seulement si l’indicateur de dessin est défini }
Canvas.LineTo(X, Y);
end;
Désormais, le dessin n’est effectué qu’entre les événements bouton de souris
enfoncé et bouton de souris relâché, mais il y a toujours cette ligne brisée qui suit le
déplacement de la souris au lieu d’une belle ligne droite.
Le problème tient à ce qu’à chaque déplacement de la souris, le gestionnaire de
l’événement déplacement de souris appelle LineTo qui déplace la position du
crayon. Par conséquent, le point d’origine de la ligne droite est perdu lorsque le
bouton de la souris est relâché.
Utilisation du multimédia
Delphi vous permet d'ajouter des composants multimédia à vos applications.
Vous pouvez le faire en ajoutant le composant TAnimate de la page Win32 ou le
composant TMediaplayer de la page Système de la palette des composants.
Utilisez le composant animation pour jouer des séquences vidéo silencieuses
dans votre application. Utilisez le composant lecteur multimédia pour jouer des
séquences audio ou vidéo dans une application.
Pour davantage d’informations sur les composants TAnimate et TMediaplayer, voir
l’aide en ligne de la VCL.
Cette section aborde les sujets suivants :
• Ajout de séquences vidéo silencieuses à une application
• Ajout de séquences audio et/ou vidéo à une application
Ecriture d’applications
Chapter 8
8
multithreads
La VCL dispose de plusieurs objets facilitant la conception d’applications
multithreads. Les applications multithreads sont des applications qui contiennent
plusieurs chemins d’exécution simultanés. Même si l’utilisation de plusieurs
threads doit être mûrement réfléchie, elle peut améliorer un programme :
• En évitant les engorgements. Avec un seul thread, un programme doit arrêter
complètement l’exécution pour attendre les processus lents comme les accès
disque, la communication avec d’autres machines ou l’affichage de données
multimédia. La CPU est inactive jusqu’à l’achèvement du processus. Avec
plusieurs threads, l’application peut poursuivre l’exécution dans des threads
séparés pendant qu’un thread attend le résultat du processus lent.
• En organisant le comportement d’un programme. Le comportement d’un
programme peut souvent être décomposé en plusieurs processus fonctionnant
de manière indépendante. L’utilisation de threads permet d’exécuter
simultanément une section de code pour chacun de ces processus. Utilisez les
threads pour assigner des priorités aux diverses tâches du programme afin
d’attribuer davantage de temps machine aux tâches critiques.
• En gérant plusieurs processeurs. Si le système exécutant le programme
dispose de plusieurs processeurs, il est possible d’améliorer les performances
en décomposant le travail en plusieurs threads s’exécutant simultanément sur
des processeurs distincts.
Remarque Tous les systèmes d’exploitation ne gèrent pas réellement l’utilisation de
plusieurs processeurs, même si cela est proposé par le matériel sous-jacent.
Par exemple, Windows 95 ne fait que simuler l’utilisation de processeurs
multiples, même si le matériel sous-jacent le gère.
Initialisation du thread
Si vous souhaitez écrire du code d'initialisation pour la nouvelle classe de thread,
vous devez écraser la méthode Create. Ajoutez un nouveau constructeur à la
déclaration de la classe de thread et écrivez le code d'initialisation pour
l'implémenter. C’est là que vous pouvez affecter une priorité par défaut au
thread et indiquer s’il doit être libéré automatiquement à la fin de son exécution.
Il y a cependant des cas où la fin d’un thread doit être coordonnée avec les
autres threads. Par exemple, il se peut que vous deviez attendre qu’un thread
renvoie une valeur avant d’effectuer une action dans un autre thread. Pour ce
faire, vous ne souhaitez pas libérer le premier thread avant que le second n’ait
reçu la valeur renvoyée. Vous pouvez traiter ce type de situation en affectant la
valeur False à FreeOnTerminate et en libérant explicitement le premier thread à
partir du second.
Remarque Comme Synchronize utilise la boucle des messages, elle ne fonctionne pas dans
les applications consoles. Vous devez utiliser d'autres mécanismes, comme les
sections critiques, pour protéger l'accès aux objets VCL dans les applications
consoles.
Il n’est pas toujours nécessaire d’utiliser le thread principal VCL. Certains objets
sont adaptés aux threads. Il est préférable de ne pas utiliser la méthode
Synchronize quand vous savez que les méthodes d’un objet sont adaptées à
l’utilisation des threads, car cela améliore les performances en évitant d’avoir à
attendre le thread principal VCL pour entrer dans la boucle de messages. Il n’est
pas nécessaire d’utiliser la méthode Synchronize dans les situations suivantes :
• Les composants d’accès aux données sont adaptés aux threads dans la mesure
où chaque thread dispose de son propre composant session de base de données.
Il n’y a qu’une seule exception : les pilotes Access. Ces pilotes sont conçus en
utilisant la bibliothèque ADO Microsoft qui n’est pas adaptée aux threads.
Lorsque vous utilisez des composants d’accès aux données, vous devez
néanmoins encadrer tous les appels aux contrôles orientés données dans la
méthode Synchronize. Ainsi, il est nécessaire de synchroniser les appels qui
relient un contrôle orienté données à un ensemble de données, mais il n’est
pas nécessaire de le faire pour accéder aux données d’un champ de l’ensemble
de données.
Pour davantage d’informations sur l’utilisation de sessions de base de données
avec les threads, voir “Gestion de plusieurs sessions” à la page 16-17.
• Les objets graphiques sont adaptés aux threads. Il n’est pas nécessaire
d’utiliser le thread principal VCL pour accéder aux objets TFont, TPen, TBrush,
TBitmap, TMetafile et TIcon. Il est possible d’accéder aux objets canevas en
dehors de la méthode Synchronize en les verrouillant (voir “Verrouillage
d’objets” à la page 8-7).
• Les listes d’objets ne sont pas adaptées aux threads, mais vous pouvez utiliser
une version adaptée aux threads, TThreadList, à la place de TList.
La section threadvar ne peut être utilisée que pour des variables globales. Les
variables pointeur et fonction ne peuvent pas être des variables de thread. Les
types utilisant une sémantique de copie lors de l’écriture, comme les chaînes
longues ne peuvent pas non plus faire office de variables de thread.
Coordination de threads
Quand vous écrivez le code exécuté lorsque le thread s’exécute, vous devez tenir
compte du comportement des autres threads qui peuvent s’exécuter
simultanément. En particulier, il faut éviter que deux threads tentent d’utiliser
simultanément le même objet ou la même variable globale. De plus, le code d’un
thread peut dépendre de tâches effectuées par d’autres threads.
Verrouillage d’objets
Certains objets disposent d’un verrouillage intégré qui empêche les autres
threads d’utiliser cette instance d’objet.
Ainsi, les objets canevas (TCanvas et ses descendants) ont une méthode Lock qui
empêche les autres threads d’accéder au canevas jusqu’à l’appel de la méthode
Unlock.
La VCL contient également un objet liste adapté aux threads, TThreadList. L’appel
de TThreadList.LockList renvoie l’objet liste tout en empêchant les autres threads
d’exécution d’utiliser la liste jusqu’à l’appel de la méthode UnlockList. Les appels
des méthodes TCanvas.Lock et TThreadList.LockList peuvent être imbriqués. Le
verrou n’est pas libéré tant que le dernier verrouillage n’est pas associé au
déverrouillage correspondant dans le même thread.
Attention Les sections critiques ne peuvent fonctionner que si tous les threads les utilisent
pour accéder à la mémoire globale associée. Les threads qui ne tiennent pas
compte des sections critiques et accèdent à la mémoire globale sans appeler
Acquire peuvent provoquer des problèmes d’accès simultanés.
Par exemple, une application a une section critique des variables globales,
LockXY, qui bloque l’accès aux variables globales X et Y. Tout thread utilisant X
ou Y doit encadrer cette utilisation d’appels à la section critique comme ci-
dessous :
LockXY.Acquire; { bloque les autres threads }
try
Y := sin(X);
finally
LockXY.Release;
end;
Le code suivant montre comment le thread principal lance les threads de tâche et
reprend la main lorsque leur exécution est achevée :
Event1.ResetEvent; { efface l’événement avant de lancer les threads }
for i := 1 to Counter do
TaskThread.Create(False); { crée et lance les threads de tâche }
if Event1.WaitFor(20000) != wrSignaled then
raise Exception;
{ poursuite avec le thread principal. L’exécution de tous les threads de tâche est achevée
}
Remarque Si vous ne voulez pas cesser d’attendre un événement après un délai spécifié,
transmettez à la méthode WaitFor une valeur de paramètre INFINITE. Faites
attention en utilisant INFINITE, car cela peut provoquer le blocage du thread si
le signal attendu n’arrive pas.
Ecriture de bibliothèques
Lorsqu’une bibliothèque active implémente l'objet distribué, l'utilisation des
threads est généralement contrôlée par la technologie (COM, DCOM ou MTS)
qui gère les appels d'objet. Lorsque vous créez votre bibliothèque serveur avec
l'expert approprié, vous êtes invité à spécifier un modèle de thread qui
détermine l'attribution des threads aux requêtes client. Ces modèles sont les
suivants :
• Modèle à thread unique. Les requêtes client sont sérialisées par le mécanisme
d'appel. Votre fichier .DLL n'est pas concerné par la gestion du thread car il
reçoit une seule requête client à un moment donné.
• Modèle appartement à thread unique. Chaque objet instancié par un client
n'est accessible que par un thread à un moment donné. Vous devez empêcher
l'accès à la mémoire globale par plusieurs threads, mais les données d'instance
(comme les propriétés d'objet) sont adaptées aux threads. De plus, chaque
client accède toujours à l'instance d'objet à l'aide du même thread, ce qui vous
permet d'utiliser des variables de thread.
• Modèle activité. Chaque instance d'objet n'est accessible que par un thread à
un moment donné mais les clients n'utilisent pas toujours le même thread
pour chaque appel. Les données d'instance sont adaptées aux threads, mais
vous devez protéger la mémoire globale, et les variables globales ne sont pas
cohérentes d'un appel client à l'autre.
• Modèle appartement à thread multiple. Chaque instance d'objet peut être
appelée par plusieurs threads simultanément. Vous devez protéger les
données d'instance ainsi que la mémoire globale. Les variables de thread ne
sont pas cohérentes d'un appel client à l'autre.
• Modèle appartement à thread unique ou multiple. Il s'agit du même modèle
que du modèle appartement à thread multiple à la différence que les rappels
émanant des clients s'exécutent dans le même thread. Ainsi, vous n'avez pas
besoin de protéger les valeurs fournies comme paramètres de fonctions de
rappel (callback).
Remarque Généralement, un expert assigne un modèle de thread à votre objet. Lorsque
vous ajoutez plusieurs objets COM à un fichier EXE, l'application s'initialise sous
COM avec le niveau indiqué de prise en charge des threads le plus élevé (le
niveau à thread unique est le plus faible et le niveau à thread unique ou
multiple est le plus élevé). Vous pouvez manuellement modifier la façon dont
votre application initialise la prise en charge des threads sous COM en
changeant la variable globale CoInitFlags dans le fichier source principal du
programme avant l'appel à Application.Intitialize.
Les systèmes basés sur COM utilisent la boucle des messages de l'application
pour synchroniser les threads dans tous les modèles (excepté le modèle
appartement à thread multiple, uniquement disponible sous DCOM). Vous devez
donc vous assurer que tout appel long opéré par le biais d'une interface COM
sollicite la méthode ProcessMessages de l'objet d'application. A défaut, les autres
clients ne peuvent pas accéder à votre application et font de votre bibliothèque
une bibliothèque à thread unique.
Remarque Les paquets partagent leurs données globales avec les autres modules d’une
application.
Pour plus d’informations sur les paquets et les DLL, voir le guide du langage Pascal
Objet.
Paquets d’exécution
Les paquets d'exécution sont déployés avec les applications Delphi. Ils
fournissent des fonctionnalités lorsqu'un utilisateur exécute une application.
Pour exécuter une application utilisant des paquets, le fichier .EXE de
l’application et tous les fichiers paquet (fichiers .BPL) qu’elle utilise doivent se
trouver sur l'ordinateur. Les fichiers .BPL doivent être dans le chemin du
système pour qu’une application puisse les utiliser. Quand vous déployez une
application, vérifiez que les utilisateurs possèdent la version correcte de chaque
BPL nécessaire.
Remarque Lorsque vous créez une application avec des paquets, vous devez inclure les
noms originels des unités Delphi dans la clause uses des fichiers source. Par
exemple, le fichier source de la fiche principale pourrait commencer ainsi :
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
Chacune des unités référencée dans cet exemple est contenu dans le paquet
VCL50. Néamoins, vous devez conserver ces références dans la clause uses,
même si vous utilisez VCL50 dans votre application, ou vous aurez des erreurs
de compilation. Dans les fichiers source générés, Delphi ajoute automatiquement
ces unités à la clause uses.
Ainsi, pour créer une application de base de données client/serveur utilisant des
paquets, vous avez besoin d'au moins deux paquets d'exécution : VCL50 et
VCLDB50. Si vous voulez également utiliser dans votre application des
composants arborescence, vous avez besoin en plus de VCLX50. Pour utiliser ces
paquets, choisissez Projet|Options, sélectionnez la page Paquets et entrez la liste
suivante dans la boîte de saisie Paquets d'exécution.
VCL50;VCLDB50;VCLX50
Il n’est, en fait, pas nécessaire de préciser VCL50, car VCL50 est référencée dans
la clause Requires de VCLDB50 (voir “La clause Requires” à la page 9-10). Votre
application se compilera de la même façon que VCL50 figure ou non dans la
liste.
Paquets personnalisés
Un paquet personnalisé est soit une BPL que vous programmez et compilez
vous-même, soit un paquet précompilé développé par un fournisseur tiers. Pour
utiliser dans une application un paquet d'exécution personnalisé, choisissez
Projet|Options et ajoutez le nom du paquet à la boîte de saisie Paquets
d'exécution de la page Paquets. Par exemple, si vous avez créé un paquet
effectuant des statistiques, nommé STATS.BPL, la boîte de saisie Paquets
d'exécution doit avoir la forme :
VCL50;VCLDB50;STATS
Si vous créez vos propres paquets, vous pouvez les ajouter selon vos besoins à la
liste.
Paquets de conception
Des paquets de conception sont utilisés pour installer des composants dans la
palette des composants de l’IDE ou pour créer les éditeurs de propriétés
spéciaux de composants personnalisés.
Delphi est livré avec les paquets composant de conception suivants, déjà installés
dans l'EDI.
La clause Requires
La clause requires spécifie les autres paquets, externes, utilisés par le paquet en
cours. Un paquet externe inclus dans la clause requires est automatiquement lié
lors de la compilation dans toute application utilisant le paquet en cours ou
l’une des unités contenues dans le paquet externe.
Si les fichiers unité contenus dans votre paquet font référence à d’autres unités
empaquetées, les autres paquets doivent apparaître dans la clause requires de
votre paquet, sinon vous devrez les ajouter. Si les autres paquets sont omis de la
clause requires, le compilateur les importera dans votre paquet comme ‘unités
contenues implicitement’.
Remarque La plupart des paquets nécessitent VCL50. Tout paquet dépendant des unités
VCL (y compris SysUtils) doit lister VCL50 ou un autre paquet nécessitant
VCL50 dans sa clause requires.
La clause Contains
La clause contains identifie les fichiers unité à lier dans le paquet. Si vous
écrivez votre propre paquet, placez votre code source dans des fichiers PAS et
incluez-les dans la clause contains.
Compilation de paquets
Vous pouvez compiler un paquet dans l’EDI ou depuis la ligne de commande.
Pour recompiler un paquet directement dans l’EDI :
1 Choisissez Fichier|Ouvrir.
2 Sélectionnez le fichier source du paquet Delphi (*.DPK) à partir de la liste
déroulante Fichiers de type.
3 Sélectionnez un fichier .DPK dans la boîte de dialogue.
4 Lorsque l’éditeur de paquet est ouvert, cliquez sur le turbobouton Compiler.
Vous pouvez insérer des directives de compilation dans le code source du paquet.
Pour plus d’informations, voir le paragraphe ci-dessous.
Si vous compilez à partir de la ligne de commande, de nouvelles options d’édition
de lien spécifiques aux paquets sont utilisables. Pour plus d’informations, voir
“Utilisation du compilateur et du lieur en ligne de commande” à la page 9-13.
Remarque Utilisez {$DENYPACKAGEUNIT ON} dans votre code pour que l’unité ne soit
pas mise dans un paquet. L’utilisation de {$G-} ou {IMPORTEDDATA OFF}
permet à un paquet de ne pas être utilisé dans la même application avec
d’autres paquets. Les paquets compilés avec la directive {$DESIGNONLY ON}
ne devrait pas être utilisés dans les applications puisque qu’ils contiennent du
code nécessaire à l’EDI. D’autres directives de compilation peuvent être utilisées
dans le code source de paquet. Voir Directives de compilation dans l’aide en
ligne pour les directives de compilation qui n’ont pas été abordées ici.
Paquets faibles
La directive $WEAKPACKAGEUNIT affecte la manière dont un fichier .DCU est
stocké dans les fichiers .DCP et .BPL d’un paquet. Pour des informations sur les
fichiers générés par le compilateur, voir “Fichiers paquets créés lors d’une
compilation réussie” à la page 9-13.) Si {$WEAKPACKAGEUNIT ON} apparaît
dans un fichier unité, le compilateur omet l’unité des BPL si c’est possible, et
crée une version locale non empaquetée de l’unité quand elle est nécessaire à
une autre application ou un autre paquet. Une unité compilée avec cette
directive est dite “faiblement empaquetée”.
Si, par exemple, vous créez un paquet appelé PACK ne contenant que l’unité
UNIT1. Supposez que UNIT1 n’utilise aucune autre unité, mais fait des appels à
RARE.DLL. Si vous placez la directive {$WEAKPACKAGEUNIT ON} dans
UNIT1.PAS, lors de la compilation du paquet, UNIT1 n’est pas incluse dans
PACK.BPL ; vous n’avez donc pas à distribuer de copie de RARE.DLL avec
PACK. Néanmoins, UNIT1 sera toujours incluse dans PACK.DCP. Si UNIT1 est
référencée dans un autre paquet ou une autre application utilisant PACK, elle
sera copiée dans PACK.DCP et directement compilée dans le projet.
Supposons maintenant que vous ajoutiez à PACK une deuxième unité, UNIT2
qui utilise UNIT1. Cette fois, même si vous compilez PACK avec la directive
{$WEAKPACKAGEUNIT ON} dans UNIT1.PAS, le compilateur inclut UNIT1
dans PACK.BPL. Par contre les autres paquets ou applications faisant référence à
UNIT1 utiliseront la copie (non empaquetée) prise dans PACK.DCP.
Remarque Les fichiers unité contenant la directive {$WEAKPACKAGEUNIT ON} ne
doivent pas contenir de variables globales, de section d’initialisation ou de
sections de finalisation.
Remarque L’utilisation de l’option -$G- empêche un paquet d’être utilisé dans une même
application avec d’autres paquets. Les autres options en ligne de commande
peuvent être utilisées de manière appropriée lors de la compilation des paquets.
Voir “Le compilateur en ligne de commande” dans l’aide en lignepour les
options en ligne de commande qui n’ont pas été abordées ici.
Le tableau suivant donne la liste des fichiers générés par une compilation réussie
d’un paquet.
Déploiement de paquets
Déploiement d’applications utilisant des paquets
Pour distribuer une application utilisant des paquets d’exécution, vérifiez que
l’utilisateur dispose du fichier .EXE de l’application, ainsi que de toutes les
bibliothèques (.BPL ou .DLL) appelées par l’application. Si les fichiers
bibliothèque sont dans un répertoire différent de celui du fichier .EXE, ils
doivent être accessibles via les chemins d’accès de l’utilisateur. Vous pouvez
suivre la convention consistant à placer les fichiers des bibliothèques dans le
répertoire Windows\System. Si vous utilisez InstallShield Express, le script
d’installation peut vérifier la présence des paquets nécessaires sur le système de
l’utilisateur avant de les réinstaller aveuglément.
5 Vous pouvez sélectionner des répertoires d’installation pour les paquets dont
la liste se trouve dans la clause requires de n’importe quel paquet de votre
collection. Lorsque vous sélectionnez un BPL dans la liste arborescente, quatre
nouveaux champs apparaissent sur la partie droite de l’éditeur de collection
de paquets :
• Dans la boîte liste Fichiers exécutables requis, sélectionnez le répertoire
dans lequel vous voulez installer les fichiers .BPL pour les paquets dont la
liste se trouve dans la clause requires. La liste déroulante comprend les
répertoires saisis dans Nom de répertoire à l’étape 3 ci-dessus. L’éditeur de
collection de paquets recherche ces fichiers en utilisant le chemin de la
bibliothèque Delphi et donne la liste sous Fichiers exécutables requis.
• Dans la boîte liste Répertoire des bibliothèques requises, sélectionnez le
répertoire d’installation des fichiers.DCP pour les paquets de la clause
requires. La liste déroulante comprend les répertoires spécifiés sous Nom
répertoire à l’étape 3, ci-dessus. L’éditeur de collection de paquets recherche
ces fichiers en utilisant le chemin de bibliothèque global de Delphi, et les
affiche sous Fichiers bibliothèque requis.
6 Pour enregistrer votre fichier source de collection de paquets, choisissez
Fichier|Enregistrer. Les fichiers source de collection de paquets doivent être
enregistrés avec l’extension .PCE.
7 Pour construire votre collection de paquets, choisissez le turbobouton
Compiler. L’éditeur de collection de paquets génère un fichier .DPC avec le
nom de votre fichier source (.PCE). Si vous n’avez pas encore enregistré le
fichier source, l’éditeur vous demande un nom de fichier avant la compilation.
Pour éditer ou recompiler un fichier .PCE existant, sélectionnez Fichier|Ouvrir
dans l’éditeur de collection de paquets.
Création d’applications
Chapter 10
10
internationales
Ce chapitre présente les règles d’écriture d’applications qui seront distribuées sur
les marchés internationaux. En planifiant le processus, il est possible de réduire
le temps et le code nécessaires pour que vos applications puissent fonctionner
parfaitement à l’étranger comme sur le marché domestique.
Internationalisation et localisation
Pour créer une application distribuable sur les marchés étrangers, vous devez
accomplir deux étapes :
• Internationalisation
• Localisation
Internationalisation
L’internationalisation est le processus permettant à votre application de
fonctionner selon divers paramètres régionaux. Les paramètres régionaux sont
l’environnement de l’utilisateur qui inclut les conventions culturelles du pays
cible aussi bien que sa langue. Windows gère un grand nombre de paramètres
régionaux, chacun d’eux décrits par l’association d’une langue et d’un pays.
Localisation
La localisation est le processus de traduction d’une application pour qu’elle
fonctionne pour des paramètres régionaux spécifiques. Outre la traduction de
l’interface utilisateur, la localisation peut également consister à personnaliser les
fonctionnalités. Par exemple, une application financière peut être modifiée afin
de respecter les règles fiscales dans différents pays.
Codage de l’application
Vous vous assurerez que le code de l’application peut gérer les chaînes qu’elle
rencontrera dans les divers environnements régionaux cible.
Jeux de caractères
Les versions de Windows diffusées aux USA utilisent le jeu de caractères ANSI
Latin-1 (1252). Mais d’autres éditions de Windows utilisent des jeux de caractères
différents. Ainsi, la version japonaise de Windows utilise le jeu de caractères
Shift-Jis (page de code 932) qui représente les caractères japonais avec des codes
sur un ou deux octets.
Lors de l’écriture de code destiné aux pays asiatiques, vous devez traiter toutes
les manipulations de chaînes avec des fonctions capables de décomposer les
chaînes en caractères de un ou deux octets. Delphi fournit un certain nombre de
fonctions de la bibliothèque d’exécution pour effectuer cela. Ces fonctions sont
les suivantes :
Caractères larges
Une autre approche des idéogrammes est de convertir tous les caractères dans
un système de caractères larges, comme Unicode. Les caractères larges utilisent
deux octets au lieu d’un, si bien qu’un jeu de ces caractères peut contenir un
nombre beaucoup plus grand d’éléments.
En outre, les caractères larges présentent un avantage sur les caractères MBCS :
ils vous permettent de conserver vos habitudes car il existe une relation directe
entre le nombre d’octets d’une chaîne et son nombre de caractères. Et, vous ne
risquez plus de couper un caractère en deux, ni de confondre la seconde moitié
d’un caractère avec la première d’un autre.
L’inconvénient majeur des caractères larges est que Windows 95 n’en reconnaît
qu’un petit nombre dans les appels aux fonctions API. C’est pourquoi, les
composants VCL représentent toutes les valeurs chaînes par des chaînes à
caractères d’un seul octet ou par des chaînes MBCS. Vous devrez passer du
système caractères larges au système MBCS à chaque fois que définir la propriété
d’une chaîne ou en lire la valeur exigerait une grande quantité de code et
ralentirait votre application. Cependant, vous pouvez souhaiter traduire en
caractères larges certains algorithmes de traitement des chaînes pour profiter de
la correspondance 1 pour 1 entre caractères et WideChars.
Propriétés bi-directionnelles
Les objets dont la liste est donnée dans le tableau 10.1, “Objets de la VCL
supportant les BiDi,” à la page 10-4 ont les propriétés : BiDiMode et
ParentBiDiMode. Ces propriétés, ainsi que BiDiKeyboard et NonBiDiKeyboard de
TApplication gèrent la localisation bi-directionnelle.
Propriété BiDiMode
La propriété BiDiMode est un nouveau type d’énuméré, TBiDiMode, qui possède
quatre états : bdLeftToRight, bdRightToLeft, bdRightToLeftNoAlign, et
bdRightToLeftReadingOnly.
bdLeftToRight
bdLeftToRight dessine le texte en utilisant le sens de lecture de gauche à droite,
l’alignement et la barre de défilement étant inchangés. Par exemple, lors de la
saisie de texte de droite à gauche, comme pour l’Arabe ou l’Hébreux, le curseur
passe en mode poussoir et le texte est saisi de droite à gauche. Pour du texte
latin, comme l’Anglais ou le Français, il est saisi de gauche à droite.
bdLeftToRight est la valeur par défaut.
Figure 10.1 Contrôles initialisés à bdLeftToRight
bdRightToLeft
bdRightToLeft dessine le texte en utilisant le sens de lecture de droite à gauche,
l’alignement étant modifié et la barre de défilement déplacée. Le texte est saisi
normalement pour les langues allant de droite à gauche comme l’Arabe ou
l’Hébreux. Lorsque le clavier est modifié pour une langue latine, le curseur passe
en mode poussoir et le texte est saisi de gauche à droite.
Figure 10.2 Contrôles initialisés à bdRightToLeft
bdRightToLeftNoAlign
bdRightToLeftNoAlign dessine le texte en utilisant le sens de lecture de droite à
gauche, l’alignement étant inchangé et la barre de défilement déplacée.
Figure 10.3 Contrôles initialisés à bdRightToLeftNoAlign
bdRightToLeftReadingOnly
bdRightToLeftReadingOnly dessine le texte en utilisant le sens de lecture de droite
à gauche, l’alignement et la barre de défilement étant inchangés.
Figure 10.4 Contrôles initialisés à bdRightToLeftReadingOnly
Propriété ParentBiDiMode
ParentBiDiMode est une propriété booléenne. Lorsqu’elle est à True (la valeur par
défaut), le contrôle regarde la propriété de son parent pour connaître la valeur à
utiliser pour BiDiMode. Si le contrôle est un objet TForm, la fiche utilise la valeur
BiDiMode de Application. Si toutes les propriétés ParentBiDiMode sont à True,
lorsque la propriété BiDiMode de Application est modifiée, toutes les fiches et tous
les contrôles du projet sont initialisés avec la nouvelle valeur.
Méthode FlipChildren
La méthode FlipChildren vous permet de faire basculer la position des enfants
d’un contrôle conteneur. Les contrôles conteneur sont des contrôles qui
contiennent d’autres contrôles, comme TForm, TPanel et TGroupbox. FlipChildren
possède un seul paramètre booléen, AllLevels. Lorsqu’il est à False, seuls les
enfants directs du contrôle conteneur sont basculés de position. Lorsqu’il est à
True, tous les enfants du contrôle conteneur sont basculés de position.
Delphi fait basculer la position des contrôles en modifiant la propriété Left et
l’alignement du contrôle. Si le côté gauche d’un contrôle est à cinq pixels de la limite
gauche de son parent, le basculement provoque l’affichage du côté droit du contrôle de
saisie à cinq pixels de la limite droite de son parent. Si le contrôle de saisie est aligné à
gauche, un appel à FlipChildren provoquera un alignement à droite.
Pour basculer la position d’un contrôle lors de la conception, il faut sélectionner
Edition|Transposer les enfants et sélectionner Tous ou Sélectionnés suivant que
vous voulez basculer la position de tous les contrôles ou seulement les enfants
du contrôle sélectionné. Il est aussi possible de basculer la position d’un contrôle
en sélectionnant le contrôle sur la fiche, en cliquant sur le bouton droit de la
souris pour sélectionner le choix Transposer les enfants dans le menu contextuel.
Remarque La sélection d’un contrôle de saisie suivi de la commande Transposer les
enfants|Sélectionnés ne fait rien. Cela est du au fait que les contrôles de saisie
ne sont pas des conteneurs.
Autres méthodes
Il existe d’autres méthodes utiles afin de développer des applications pour des
utilisateurs bi-directionnels.
Méthode Description
OkToChangeFieldAlignment Utilisée avec les contrôles base de données. Vérifie si
l’alignement d’un contrôle peut être modifié.
DBUseRightToLeftAlignment Utilisée pour vérifier l’alignement des contrôles base
de données.
ChangeBiDiModeAlignment Modifie le paramètre d’alignement qui lui est
transmis. Aucune vérification n’est faite pour
l’initialisation de BiDiMode, car il y a juste
conversion de l’alignement à gauche vers
l’alignement à droite et vice-versa, en laissant centré
les contrôles seuls.
Méthode Description
IsRightToLeft Renvoie True si une des options allant de droite à
gauche est sélectionnée. Renvoie False si le contrôle
est dans un mode allant de gauche à droite.
UseRightToLeftReading Renvoie True si le contrôle utilise le sens de lecture
allant de droite à gauche.
UseRightToLeftAlignment Renvoie True si le contrôle utilise le sens
d’alignement allant de droite à gauche. Il peut être
surchagé pour être personnalisé.
UseRightToLeftScrollBar Renvoie True si le contrôle utilise une barre de
défilement à gauche.
DrawTextBiDiModeFlags Renvoie les bons paramètres pour le mode BiDi du
contrôle.
DrawTextBiDiModeFlagsReadingOnly Renvoie les bons paramètres pour le mode BiDi du
contrôle, en les limitant à la lecture.
AddBiDiModeExStyle Ajoute le paramètre ExStyle flags approprié au
contrôle créé.
Texte
Tout le texte apparaissant dans l’interface utilisateur doit être traduit. Le texte
anglais étant presque toujours plus court que les traductions, vous devez
concevoir les éléments de votre interface utilisateur qui affiche du texte en
réservant de l’espace pour l’expansion de ce texte. Concevez également les boîtes
de dialogue, les menus, les barres d’état et les autres éléments de l’interface
utilisateur affichant du texte de telle sorte qu’ils puissent facilement afficher des
chaînes plus longues. Evitez les abréviations qui ne peuvent exister dans les
langues utilisant des idéogrammes.
Les chaînes courtes grandissent plus que les phrases longues. Le tableau suivant
fournit une approximation des taux de foisonnement selon la longueur de la
chaîne initiale (en anglais) :
Tableau 10.2 Estimation des longueurs de chaîne
Longueur de la chaîne anglaise (en
caractères) Augmentation prévisible
1-5 100%
6-12 80%
13-20 60%
21-30 40%
31-50 20%
over 50 10%
Images graphiques
Le mieux est d’utiliser des images qui ne nécessitent pas de traduction, c’est-à-
dire des images qui ne contiennent pas de texte. Si vous devez inclure du texte
dans vos images, il est préférable d’utiliser un objet libellé avec arrière-plan
transparent par dessus l’image, plutôt que d’inclure le texte dans l’image elle-
même.
Voici quelques autres considérations à prendre en compte lors de la création des
images graphiques. Essayez d’éviter les images spécifiques à une culture. Par
exemple, les boîtes à lettres sont très différentes selon les pays. Les symboles
religieux ne conviennent pas aux pays où il existe plusieurs religions
dominantes. Même les couleurs ont des connotations symboliques différentes
selon les cultures.
L’ordre dans lequel les chaînes sont classées dépend également du pays. De
nombreuses langues européennes utilisent des caractères accentués et sont
classées différemment selon les paramètres régionaux. En outre, certaines
combinaisons de deux caractères peuvent être traitées par le tri comme un seul
caractère. Par exemple, en espagnol, la combinaison ch est triée comme étant un
caractère unique compris entre le c et le d. Parfois, un caractère est trié comme
s’il s’agissait de deux caractères séparés, par exemple le eszett allemand.
Vous devez créer un module de ressource pour chaque traduction que vous
voulez gérer. Chaque module de ressource doit avoir une extension du nom de
fichier spécifique à la localisation cible. Les deux premiers caractères indiquent la
langue cible et le troisième le pays pour la localisation. Si vous utilisez l’expert
Ressource DLL, cela est géré pour vous. Sinon, utilisez le code suivant pour
obtenir le code local de la traduction cible :
unit locales;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
LocaleList: TListBox;
procedure Button1Click(Sender: TObject);
private
{ déclarations privées }
public
{ déclarations publiques }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function GetLocaleData(ID: LCID; Flag: DWORD): string;
var
BufSize: Integer;
begin
BufSize := GetLocaleInfo(ID, Flag, nil, 0);
SetLength(Result, BufSize);
GetLocaleinfo(ID, Flag, PChar(Result), BufSize);
SetLength(Result, BufSize - 1);
end;
{ Appelé pour chaque localisation supportée. }
function LocalesCallback(Name: PChar): Bool; stdcall ;
var
LCID: Integer;
begin
LCID := StrToInt('$' + Copy(Name, 5, 4));
Form1.LocaleList.Items.Add(GetLocaleData(LCID, LOCALE_SLANGUAGE));
Result := Bool(1);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumSystemLocales(@LocalesCallback, LCID_SUPPORTED);
end;
end.
Les applications Delphi qui accèdent à des bases de données ou qui fonctionnent
sur le Web nécessitent des étapes complémentaires d’installation en plus de
celles s’appliquant aux applications générales. Pour davantage d’informations sur
l’installation d’applications de base de données, voir “Déploiement d’applications
de base de données” à la page 11-4. Pour davantage d’informations sur
l’installation d’applications Web, voir “Déploiement d’applications Web” à la
page 11-7. Pour davantage d’informations sur l’installation de contrôles ActiveX,
voir “Déploiement d’un contrôle ActiveX sur le Web” à la page 48-19. Pour des
informations sur le déploiement d’applications CORBA, voir “Déploiement
d’applications CORBA” à la page 28-18.
Fichiers paquet
Si l’application utilise des paquets d’exécution, il faut distribuer les fichiers
paquet avec l’application. InstallShield Express gère l’installation des fichiers
paquet de la même manière que les DLL, copie ces fichiers et crée les entrées
nécessaires dans les registres Windows. Borland recommande l’installation des
fichiers paquet d’exécution d’origine Borland dans le répertoire Windows\
System. Cela sert d’emplacement commun afin que plusieurs applications
puissent accéder à une seule instance de ces fichiers. Pour les paquets que vous
avez créés, il est recommandé de les installer dans le répertoire de l’application.
Seuls les fichiers .BPL doivent être distribués.
Si vous distribuez des paquets à d’autres développeurs, fournissez les fichiers
.BPL et .DCP.
Contrôles ActiveX
Certains composants fournis avec Delphi sont des contrôles ActiveX. Le
conteneur du composant est lié au fichier exécutable de l’application (ou à un
paquet d’exécution), mais le fichier .OCX du composant doit également être
distribué avec l’application. Ces composants sont :
• Chart FX, copyright par SoftwareFX Inc.
• VisualSpeller Control, copyright par Visual Components, Inc.
• Formula One (tableur), copyright par Visual Components, Inc.
• First Impression (VtChart), copyright par Visual Components, Inc.
• Graph Custom Control, copyright par Bits Per Second Ltd.
Les contrôles ActiveX que vous créez doivent également être enregistrés sur
l’ordinateur cible avant d’être utilisés. Les programmes d’installation comme
InstallShield Express automatisent le processus d’enregistrement. Pour enregistrer
manuellement un contrôle ActiveX, utilisez l’application exempleTRegSvr ou
l’utilitaire Microsoft REGSRV32.EXE (qui n’est pas inclus dans toutes les versions
de Windows).
Les fichiers DLL gérant un contrôle ActiveX doivent également être distribués
avec une application.
Applications complémentaires
Les applications complémentaires sont des programmes distincts en l’absence
desquels votre application Delphi fonctionnerait de manière incomplète ou ne
fonctionnerait pas du tout. Les applications complémentaires peuvent être celles
fournies avec Windows, par InPrise ou des tiers. Le programme utilitaire Server
Manager de InterBase est un exemple de programme complémentaire qui permet
de gérer les utilisateurs et la sécurité des bases de données InterBase.
Si une application dépend d’un programme complémentaire, assurez-vous de le
déployer avec votre application, si c’est possible. La distribution des programmes
complémentaires peut être limitée par des accords de licence de distribution.
Consultez la documentation d’un programme complémentaire pour des
informations spécifiques.
SQL Links
SQL Links propose les pilotes permettant de connecter une application au
logiciel client d’une base de données SQL (via le moteur de bases de données
Borland). Voir DEPLOY.TXT pour les droits et restrictions spécifiques
s’appliquant à la redistribution de SQL Links. Comme pour le moteur de bases
de données Borland, SQL Links doit être déployé en utilisant InstallShield
Express (ou tout autre programme certifié).
Remarque SQL Links connecte le BDE au logiciel client et pas directement à la base de
données SQL même. Il est donc toujours nécessaire d’installer le programme
client du système de bases de données SQL utilisé. Reportez-vous à la
documentation de votre système SQL ou consultez le vendeur pour davantage
d’informations sur l’installation et la configuration du logiciel client.
Tableau 11.2 Fichiers des logiciels client des bases de données SQL
Vendeur Fichiers redistribuables
Oracle 7 SQLORA32.DLL et SQL_ORA.CNF
Oracle8 SQLORA8.DLL et SQL_ORA8.CNF
Sybase Db-Lib SQLSYB32.DLL et SQL_SYB.CNF
Sybase Ct-Lib SQLSSC32.DLL et SQL_SSC.CNF
Microsoft SQL Server SQLMSS32.DLL et SQL_MSS.CNF
Informix 7 SQLINF32.DLL et SQL_INF.CNF
Informix 9 SQLINF9.DLL et SQL_INF9.CNF
DB/2 SQLDB232.DLL et SQL_DB2.CNF
InterBase SQLINT32.DLL et SQL_INT.CNF
La liste suivante indique les fichiers devant être installés sur la machine client.
NBASE.IDL ODEN40.DLL RPMFEN40.DLL OLENTEXP.EXE
ODECTN40.DLL RPMARN40.DLL RPMUTN40.DLL SETLOG.EXE
ODEDIN40.DLL RPMAWN40.DLL OLERAN40.DLL OLECFG.EXE
ODEEGN40.DLL RPMCBN40.DLL OLEAAN40.DLL W32PTHD.DLL
ODELTN40.DLL RPMCPN40.DLL OLEWAN40.CAB
ODEMSG.DLL RPMEGN40.DLL OBJX.EXE
• La sécurité définie pour les répertoires ne doit pas être trop restrictive afin
que soit possible l’accès aux fichiers de l’application, au BDE ou aux fichiers
de données.
• Le répertoire contenant une application doit avoir des attributs de lecture et
d’exécution.
• L’application ne doit pas utiliser de chemins d’accès codés “en dur” pour
accéder aux bases de données et aux autres fichiers.
• L’emplacement d’un contrôle ActiveX est indiqué par le paramètre
CODEBASE de la balise HTML <OBJECT>.
Fontes
Windows dispose d’un jeu standard de fontes TrueType et vectorielles. Quand
vous concevez une application devant être déployée sur d’autres ordinateurs,
tenez compte du fait que tous les ordinateurs n’ont pas nécessairement de fontes
en-dehors du jeu Windows standard.
Les composants texte utilisés dans l’application ne doivent utiliser que des fontes
qui sont très probablement disponibles sur les ordinateurs cible.
Quand l’utilisation d’une fonte non standard est absolument nécessaire dans une
application, vous devez distribuer cette fonte avec l’application. Soit le
programme d’installation, soit l’application même doit installer la fonte sur
l’ordinateur cible. La distribution de fontes créées par des tiers peut être sujette à
des restrictions imposées par leurs créateurs.
Windows dispose d’une protection contre l’utilisation d’une fonte inexistante sur
un système. Il lui substitue une fonte existante, la plus proche possible. Bien que
cela empêche les erreurs dues à des fontes manquantes, le résultat final peut
dégrader l’aspect visuel de l’application. Il est préférable de prévoir cette
éventualité à la conception.
Pour mettre à la disposition d’une application une fonte non standard, utilisez
les fonctions AddFontResource et DeleteFontResource de l’API Windows. Déployez
les fichiers .FOT des fontes non-standard avec l’application.
Versions de Windows
Quand vous utilisez des fonctions de l’API Windows ou si vous accédez à des
zones du système d’exploitation Windows dans une application, il y a le risque
que cette fonction, cette opération ou cette zone ne soit pas disponible sur des
ordinateurs utilisant une version différente de Windows. Par exemple, les
services n’ont de sens que pour le système d’exploitation Windows NT. Si une
application doit se comporter comme un service ou doit interagir avec un
service, elle ne fonctionnera pas si l’application est installée sous Windows 95.
Pour prendre cette possibilité en compte, vous avez différentes possibilités :
• Spécifiez dans les spécifications logicielles de l’application les versions de
Windows sous lesquelles l’application peut s’exécuter. C’est alors à l’utilisateur
de n’installer et de n’utiliser l’application que dans des versions compatibles
de Windows.
• Testez la version de Windows lors de l’installation de l’application. Si une
version incompatible de Windows est détectée, arrêtez le processus
d’installation ou prévenez l’utilisateur du problème.
• Testez la version de Windows à l’exécution, juste avant d’exécuter une
opération qui n’est pas applicable à toutes les versions. Si une version
incompatible de Windows est détectée, abandonnez l’opération et informez
l’utilisateur. Vous pouvez aussi utiliser du code différent pour les différentes
versions de Windows. Certaines opérations s’effectuent différemment sous
Windows 95 et sous Windows NT. Utilisez la fonction GetVersionEx de l’API
Windows pour déterminer la version de Windows.
DEPLOY.TXT
DEPLOY.TXT aborde certains aspects légaux de la distribution de divers
composants et utilitaires et autres produits pouvant faire partie ou être associés à
une application C++BuilderDelphi. DEPLOY.TXT est un fichier texte installé dans
le répertoire principal de C++BuilderDelphi. Il aborde les sujets suivants,
• Les fichiers .EXE, .DLL et .BPL
• Les composants et les paquets de conception
• Le moteur de bases de données Borland (BDE)
• Les contrôles ActiveX
• Les images exemple
• MIDAS
• SQL Links
README.TXT
README.TXT contient des informations de dernière minute sur
C++BuilderDelphi ; il peut donc contenir des informations pouvant affecter les
droits de redistribution des composants, utilitaires ou autres éléments.
README.TXT est un fichier d’aide Windows installé dans le répertoire principal
de C++BuilderDelphi.
Contrat de licence
Le contrat de licence C++BuilderDelphi est un document imprimé qui traite des
droits et obligations légales concernant C++BuilderDelphi.
II
Développement d’applications
Part II
de base de données
Les chapitres de cette partie présentent les concepts et les connaissances
nécessaires à la création d’applications de base de données Delphi.
Remarque Vous avez besoin de l’édition Professionnelle ou Entreprise de Delphi pour
développer des applications de base de données. Pour implémenter des bases de
données Client/Serveur plus évoluées, vous avez besoin des caractéristiques de
Delphi disponibles dans l’édition Entreprise.
Conception d’applications de
Chapter 12
12
bases de données
Les applications de bases de données permettent aux utilisateurs d’interagir avec
les informations stockées dans les bases de données. Les bases de données
permettent de structurer les informations et de les partager entre plusieurs
applications.
Delphi permet de gérer les applications de bases de données relationnelles. Les
bases de données relationnelles organisent les informations en tables, qui
contiennent des lignes (enregistrements) et des colonnes (champs). Ces tables
peuvent être manipulées par des opérations simples appelées calculs relationnels.
Lorsque vous concevez une application de bases de données, vous devez
comprendre comment les données sont structurées. A partir de cette structure,
vous pouvez concevoir une interface utilisateur pour afficher les données et
permettre à l’utilisateur d’entrer de nouvelles informations et de modifier les
données existantes.
Ce chapitre présente certains aspects courants de la conception d’une application
de bases de données et les décisions inhérentes à la conception d’une interface
utilisateur.
Transactions
Une transaction est un groupe d’actions qui doivent être menées avec succès sur
une ou plusieurs tables dans une base de données avant d’être validées (rendues
définitives). Si l’une des actions du groupe échoue, toutes les actions sont
abandonnées (annulées).
Les transactions protègent contre les défaillances matérielles qui se produisent au
milieu d’une commande de base de données ou d’un ensemble de commandes.
Elle constituent aussi la base du contrôle simultané de plusieurs utilisateurs sur
les serveurs SQL. Lorsque tous les utilisateurs interagissent avec la base de
données par le biais de transactions, les commandes d’un utilisateur ne peuvent
pas altérer l’unité d’une transaction d’un autre utilisateur ; le serveur SQL
planifie les transactions entrantes, qui réussissent ou échouent en bloc.
Bien que le support des transactions ne fasse pas partie de la plupart des bases
de données locales, les pilotes du moteur de bases de données Borland offrent
pour certaines un support des transactions limité. Pour les serveurs SQL et les
bases de données de type ODBC, le support des transactions de base de données
est fourni par le composant qui représente la connexion à la base de données.
Dans les applications multiniveaux, vous pouvez créer des transactions qui
comprennent des actions autres que des opérations de base de données ou qui
englobent plusieurs bases de données.
Pour plus de détails sur l’utilisation des transactions dans les applications basées
sur le moteur de bases de données Borland, voir “Utilisation des transactions” à
la page 13-5. Pour plus de détails sur l’utilisation des transactions dans les
applications basées sur ADO, voir “Utilisation des transactions de connexion” à
la page 23-11. Pour plus de détails sur l’utilisation des transactions dans les
applications multiniveaux, voir “Gestion des transactions dans les applications
multiniveaux” à la page 14-29 . Pour plus de détails sur l’utilisation des
transactions dans les applications qui utilisent les composants d’accès direct à
InterBase, voir l’aide en ligne pour le composant TIBTransaction.
Dictionnaire de données
Quand vous utilisez le BDE pour accéder à vos données, votre application peut
accéder au dictionnaire de données. Le dictionnaire de données offre une zone
de stockage paramétrable, indépendante de vos applications, dans laquelle vous
pouvez créer des ensembles d’attributs de champ étendus qui décrivent le
contenu et l’aspect des données.
Par exemple, si vous êtes souvent amené à développer des applications
financières, vous pouvez créer un certain nombre d’ensembles spécialisés
d’attributs de champ pour décrire les différents formats d’affichage monétaire. Si
ensuite, lors de la conception, vous créez un ensemble de données dans une
application, plutôt que d’utiliser l’inspecteur d’objets pour définir manuellement
les champs monétaires de l’ensemble de données, vous pouvez associer ces
champs à un ensemble d’attributs de champ étendus dans le dictionnaire de
données. L’utilisation du dictionnaire de données permet d’homogénéiser l’aspect
des données sur toutes les applications que vous créez.
Si les informations ne sont pas destinées à être partagées, vous pouvez utiliser
une base de données locale dans une application à niveau unique. Cette approche
présente l’avantage de la rapidité (car les données sont stockées localement) et ne
nécessite pas l’achat d’un serveur de bases de données séparé ni de licences de
site onéreuses. Toutefois, elle est limitée par la quantité de données pouvant être
contenues dans les tables et par le nombre d’utilisateurs pouvant être pris en
charge par votre application.
L’écriture d’une application à niveau double permet de gérer davantage
d’utilisateurs et d’utiliser des bases de données volumineuses distantes stockant
beaucoup plus d’informations.
Remarque La gestion des applications à niveau double requiert SQL Links, InterBase ou
ADO .
Lorsque les informations de base de données comprennent des relations
complexes entre plusieurs tables ou que le nombre de clients s’accroît, vous
pouvez utiliser une application multiniveau. Les applications multiniveaux
comprennent des niveaux intermédiaires qui centralisent la logique qui gouverne
les interactions avec votre base de données et offrent ainsi un contrôle centralisé
des relations entre les données. Cela permet à différentes applications clientes
d’utiliser les mêmes données tout en garantissant l’homogénéité de la logique
des données. Les applications multiniveaux autorisent aussi les applications
clientes de taille réduite car la majeure partie du traitement est déplacée vers les
niveaux intermédiaires. Ces applications clientes de taille réduite sont plus faciles
à installer, à configurer et à gérer car elles ne comprennent pas de logiciel de
connectivité de base de données. Les applications multiniveaux peuvent aussi
améliorer la performance en répartissant les tâches de traitement des données sur
plusieurs systèmes.
Anticipation de l’évolutivité
Le processus de développement peut s’avérer plus prenant et onéreux au fur et à
mesure que le nombre de niveaux s’accroît. C’est pourquoi vous pouvez
commencer par développer une application à niveau unique. L’augmentation de
la quantité de données, du nombre d’utilisateurs et du nombre des différentes
applications accédant aux données vous obligera peut-être à adopter une
architecture multiniveau. En anticipant l’évolutivité, vous pouvez protéger vos
investissements en développement d’applications à niveau unique ou à niveau
double par la réutilisation de votre code au fur et à mesure que votre application
s’accroît.
Les composants orientés données de la VCL facilitent l’écriture d’applications
évolutives en cernant le comportement de la base de données et des données
qu’elle stocke. Que vous écriviez une application à niveau unique, à niveau
double ou multiniveau, vous pouvez isoler votre interface utilisateur de la
couche d’accès aux données comme le montre la figure 12.1.
Figure 12.1 Interface utilisateur des connexions aux ensembles de données dans
toutes applications de base de données
composant base de
éléments source ensemble données
d'interface de données OLE DB
de données distante
utilisateur
ADO
Application Client
composant Moteur
éléments source ensemble base de base de
d'interface de données de données données données
utilisateur BDE Borland distante
Application Client
Dans ce modèle, toutes les applications sont des clients de base de données. Un
client demande des informations à un serveur de bases de données et lui en
envoie. Un serveur peut traiter les requêtes de nombreux clients simultanément,
en coordonnant l’accès aux données et leur mise à jour.
Pour plus d’informations sur la construction d’applications de base de données à
niveau double, voir “Applications basées sur le BDE” à la page 13-2 et “Applications
basées sur ADO” à la page 13-12.
composant fournisseur
connexion
Moteur
éléments base de
source
d'interface composant données base de
de données ensemble
utilisateur ensemble Borland données
de données distante
de données
client
BDE
composant fournisseur
connexion
base de
éléments données
source distante
d'interface composant
de données ensemble
utilisateur ensemble
de données
de données OLE DB
client
ADO
composant fournisseur
connexion
éléments
source
d'interface
de données ensemble ensemble
utilisateur
de données de données
client personnalisé
Delphi peut être utilisé pour créer les applications client et les serveurs
d’applications. Comme l’illustre la figure précédente, dans une application client,
des contrôles orientés données standard connectés à une source de données par
l’intermédiaire d’un ou de plusieurs composants ensemble de données
permettent d’afficher et de modifier des données. Chaque ensemble de données
client communique avec un serveur d’applications par l’intermédiaire d’une
interface IAppServer implémentée par le module de données du serveur
d’applications distant. L’application client peut utiliser une série de protocoles
(TCP/IP, DCOM, MTS, CORBA) pour établir cette communication. Le protocole
dépend du type de composant connexion utilisé dans l’application client et du
type de module de données distant utilisé dans l’application serveur.
Le serveur d’applications inclut des composants fournisseur qui supportent la
communication entre les ensembles de données client de l’application client et les
ensembles de données du serveur d’applications. Toutes les données sont passées
entre l’application client et les composants fournisseur via l’interface IAppServer.
Vous pouvez utiliser l’un quelconque des types d’ensemble de données suivants :
• Composants table (TTable) : les tables correspondent directement aux tables
sous-jacentes de la base de données. Vous pouvez définir quels champs
apparaissent (et même ajouter des champs de référence et des champs
calculés) en utilisant des composants champ persistant. Vous pouvez limiter
les enregistrements qui apparaissent en utilisant des plages ou des filtres. Les
tables sont décrites de façon plus détaillée dans le chapitre 20, “Manipulation
des tables”. Les champs persistants sont décrits dans “Champs persistants” à
la page 19-4. Les plages et les filtres sont décrits dans “Manipulation d’un
sous-ensemble de données” à la page 20-12.
• Composants requête (TQuery) : les requêtes offrent le mécanisme le plus
général pour spécifier le contenu d’un ensemble de données basé sur le BDE.
Vous pouvez combiner les données de plusieurs tables en utilisant des
jointures et limiter les champs et les enregistrements qui apparaissent en
fonction de critères exprimés en langage SQL. Pour plus d’informations sur les
requêtes, voir chapitre 21, “Manipulation des requêtes”.
• Procédures stockées (TStoredProc) : les procédures stockées sont des
ensembles d’instructions SQL qui sont nommées et stockées sur un serveur
SQL. Si votre serveur de bases de données définit une procédure distante qui
renvoie l’ensemble de données que vous souhaitez, vous pouvez utiliser un
composant procédure stockée. Pour plus d’informations sur les procédures
stockées, voir chapitre 22, “Manipulation des procédures stockées”.
• Ensembles de données imbriqués (TNestedTable) : les ensembles de données
imbriqués représentent les enregistrements d’un ensemble détail Oracle8
imbriqué. Delphi ne vous permet pas de créer des tables Oracle8 contenant
des champs ensemble de données imbriqués, mais vous pouvez modifier et
afficher les données provenant de champs ensemble de données existants à
l’aide d’ensembles de données imbriqués. L’ensemble de données imbriqué
obtient ses données à partir d’un composant champ ensemble de données
d’un ensemble de données contenant des données Oracle8. Voir “Utilisation
des tables imbriquées” à la page 20-29 et “Utilisation des champs ensemble de
données” à la page 19-30 pour plus d’informations sur la représentation des
champs ensemble de données à l’aide des ensembles de données imbriqués.
Quand vous utilisez ADO pour accéder à vos données, vous pouvez utiliser l’un
quelconque des types d’ensembles de données suivants :
• Ensembles de données ADO (TADODataset) : les ensembles de données
ADO offrent le mécanisme le plus souple pour accéder aux données en
utilisant ADO. Les ensembles de données ADO peuvent représenter une seule
table de base de données ou les résultats d’une requête SQL. Vous pouvez
définir quels champs apparaissent (et même ajouter des champs de référence
et des champs calculés) en utilisant des composants champ persistant. Vous
pouvez limiter les enregistrements qui apparaissent en utilisant des plages ou
des filtres. Vous pouvez spécifier une instruction SQL qui génère les données.
Les ensembles de données ADO sont décrits en détail dans “Caractéristiques
communes à tous les composants ensemble de données ADO” à la page 23-13
et “Utilisation de TADODataSet” à la page 23-20.
Ecriture de rapports
Si vous souhaitez que les utilisateurs puissent imprimer les informations de base
de données émanant des ensembles de données de votre application, vous
pouvez utiliser les composants rapport de la page QReport de la palette des
composants. L’utilisation de ces composants vous permet de construire
visuellement des rapports à bandes pour présenter et résumer les informations
contenues dans vos tables de base de données. Vous pouvez ajouter des résumés
aux en-têtes et aux pieds de page de groupe pour analyser les données en
fonction de critères de regroupement.
Démarrez un rapport pour votre application en sélectionnant l’icône QuickReport
dans la boîte de dialogue Nouveaux éléments. Sélectionnez Fichier|Nouveau
dans le menu principal et allez à la page Affaires. Double-cliquez sur l’icône
Expert QuickReport pour lancer l’expert.
Remarque Pour un exemple d’utilisation des composants de la page QReport, reportez-vous
au programme exemple QuickReport livré avec Delphi.
Par exemple, dans une application bancaire, le transfert de fonds d’un compte
vers un autre est une opération qui mérite d’être protégée avec une transaction.
Si, après diminution du solde d’un compte, une erreur se produit dans
l’augmentation du solde de l’autre compte, il est souhaitable d’annuler la
transaction afin que la base de données continue de refléter le solde total correct.
Par défaut, le BDE permet de contrôler explicitement les transactions de vos
applications. Lorsqu’une application est placée sous contrôle implicite des
transactions, une transaction séparée est utilisée pour chaque enregistrement de
l’ensemble de données écrit dans la base de données sous-jacente. Les
transactions implicites réduisent au minimum les conflits de mise à jour des
enregistrements et garantissent l’homogénéité de la vue de la base de données.
D’un autre côté, comme chaque ligne de données écrite dans une base de
données occupe de la place dans sa propre transaction, le contrôle des
transactions implicites peut générer un trafic réseau excessif et ralentir la
performance de l’application. De plus, le contrôle des transactions implicites ne
protège pas les opérations logiques qui englobent plusieurs enregistrements,
comme le transfert de fonds précédemment décrit.
Si vous contrôlez les transactions de façon explicite, vous pouvez efficacement
décider à quel moment les démarrer, les valider et les annuler. Lorsque vous
développez des applications dans un environnement multi-utilisateur, notamment
lorsque vos applications utilisent un serveur SQL distant, vous devez contrôler
les transactions de façon explicite.
Remarque Vous pouvez réduire au minimum le nombre de transactions requises en mettant
les mises à jour en mémoire cache. Pour plus d’informations sur les mises à jour
mises en mémoire cache, voir chapitre 25, “Manipulation des mises à jour en
mémoire cache”
Les applications à niveau unique ne peuvent pas utiliser SQL direct. Vous
pouvez utiliser le composant base de données pour créer des transactions
explicites pour les bases de données locales. Toutefois, il y a certains limites à
l’utilisation des transactions locales. Pour plus d’informations sur l’utilisation des
transactions locales, voir “Utilisation des transactions locales” à la page 13-10.
Lorsque vous écrivez des applications à niveau double (qui requièrent SQL
Links), vous pouvez utiliser un composant base de données ou SQL direct pour
gérer les transactions. Pour plus d’informations sur l’utilisation de SQL direct,
voir “Utilisation du SQL direct” à la page 13-9.
Remarque Lorsque vous utilisez des transactions avec des tables locales Paradox, dBASE,
Access et FoxPro, mettez TransIsolation à tiDirtyRead plutôt que d’utiliser la
valeur par défaut de tiReadCommitted. Une erreur BDE est renvoyée si
TransIsolation a une valeur autre que tiDirtyRead pour les tables locales.
Lorsqu’une application utilise ODBC pour s’interfacer avec un serveur, il faut
que le pilote ODBC supporte aussi le niveau d’isolement voulu. Pour plus
d’informations, reportez-vous à la documentation de votre pilote ODBC.
Remarque Lorsque vous créez des tables Oracle8, vous ne pouvez pas créer de champs
objet (champs ADT, champs tableau, champs de référence et champs ensemble
de données).
Si vous souhaitez restructurer une table en mode exécution (autrement qu’en
ajoutant des index), vous devez utiliser l’API du BDE DbiDoRestructure. Vous
pouvez ajouter des index à toute table existante à l’aide de la méthode AddIndex
de TTable.
Remarque En mode conception, vous pouvez utiliser le Module base de données pour créer
et restructurer des tables Paradox et dBASE. Pour créer et restructurer des tables
sur des serveurs distants, utilisez l’explorateur SQL et restructurez les tables à
l’aide de SQL.
CaseInsFields vous permet de définir des index qui trient les enregistrements en
tenant compte de la casse sur certains champs et sans en tenir compte sur
d’autres. Au lieu d’utiliser l’option isCaseInsensitive pour trier tous les champs de
l’index en tenant compte de la casse, spécifiez uniquement les champs à trier
sans tenir compte de la casse sous la valeur CaseInsFields. Comme DescFields,
CaseInsFields accepte une liste de noms de champ séparés par des points-virgules.
Vous pouvez spécifier les définitions de champ et d’index en mode conception à
l’aide de l’éditeur de collection. Il suffit de choisir la propriété appropriée dans
l’inspecteur d’objets (FieldDefs ou IndexDefs) et de double-cliquer pour afficher
l’éditeur de collection. Utilisez l’éditeur de collection pour ajouter, supprimer et
réorganiser les définitions. En sélectionnant les définitions dans l’éditeur de
collection, vous pouvez modifier leurs propriétés dans l’inspecteur d’objets.
Vous pouvez aussi spécifier les définitions de champ et d’index dans du code en
mode exécution. Par exemple, le code suivant crée et active un ensemble de
données client dans le gestionnaire d’événements OnCreate de la fiche :
procedure TForm1.FormCreate(Sender: TObject);
begin
with ClientDataSet1 do
begin
with FieldDefs.AddFieldDef do
begin
DataType := ftInteger;
Name := 'Field1';
end;
with FieldDefs.AddFieldDef do
begin
DataType := ftString;
Size := 10;
Name := 'Field2';
end;
with IndexDefs.AddIndexDef do
begin
Fields := 'Field1';
Name := 'IntIndex';
end;
CreateDataSet;
end;
end;
4 Dans l’application client, ajoutez du code pour appliquer les mises à jour dans
le serveur d’applications. Pour plus d’informations sur l’envoi de mises à jour
à partir d’une application client vers un serveur d’applications, voir “Mise à
jour des enregistrements” à la page 24-24.
Utilisation de MTS
L’utilisation de MTS permet à votre module de données distant de tirer parti des
éléments suivants :
• Sécurité MTS. MTS offre à votre serveur d’applications une sécurité à base de
rôles. Des rôles sont attribués aux clients et déterminent comment ces derniers
peuvent accéder à l’interface du module de données MTS. Le module de
données MTS implémente la méthode IsCallerInRole, qui vous permet de
vérifier le rôle du client alors connecté et d’autoriser certaines fonctions selon
ce rôle. Pour plus d’informations sur la sécurité MTS, voir “Sécurité en
fonction des rôles” à la page 50-12.
• Regroupement des handles de base de données. Les modules de données
MTS regroupent automatiquement les connexions de base de données de sorte
que, lorsqu’un client n’utilise plus une connexion de base de données, un
autre client la réutilise. Ceci allège le trafic réseau car votre niveau
Attention Lorsque vous utilisez MTS, les connexions aux bases de données ne doivent pas
être ouvertes avant l’activation du module de données distant. Pendant le
développement de votre application, assurez-vous que tous les ensembles de
données sont inactifs et que la base de données n’est pas connectée avant
l’exécution de votre application. Dans l’application elle-même, vous devez ajouter
du code pour ouvrir les connexions de base de données lors de l’activation du
module de données et pour les fermer lors de sa désactivation.
Tant qu’il n’a pas libéré une référence aux interfaces sur le serveur
d’applications, le protocole Sockets n’offre aucune protection sur le serveur
contre les défaillances système client. Tout en générant moins de trafic de
messages que DCOM (qui envoie périodiquement des messages), l’utilisation de
Sockets peut aboutir à la situation dans laquelle un serveur d’applications, non
conscient de la déconnexion du client, ne libère pas ses ressources.
Utilisation de OLEnterprise
OLEnterprise vous permet d’utiliser le courtier d’objets d’entreprise au lieu du
courtage côté client. Le courtier d’objets d’entreprise offre la répartition
équilibrée de la charge, le basculement de serveur et la transparence de
localisation.
Lorsque vous utilisez OLEnterprise, vous devez installer le runtime OLEnterprise
sur les systèmes client et serveur. Le runtime OLEnterprise gère le tri des appels
Automation et communique entre les systèmes client et serveur à l’aide d’appels
de procédures à distance (RPC). Pour plus d’informations, reportez-vous à la
documentation OLEnterprise.
Remarque Les modules de données distants sont plus que de simples modules de
données. Le module de données distant CORBA fait office de serveur CORBA.
Les autres modules de données sont des objets COM Automation.
2 Placez sur le module de données les composants ensemble de données
appropriés, et configurez-les pour accéder au serveur de base de données.
3 Placez sur le module de données un composant TDataSetProvider pour chaque
ensemble de données. Ce fournisseur est nécessaire au courtage des demandes
client et à l’empaquetage des données.
4 Attribuez à la propriété DataSet de chaque composant fournisseur le nom de
l’ensemble de données devant être accessible. Vous pouvez définir d’autres
propriétés pour le fournisseur. Pour plus de détails sur la configuration d’un
fournisseur, voir chapitre 15, “Utilisation des composants fournisseur”.
5 Ecrivez du code pour le serveur d’applications afin d’implémenter les
événements, les règles d’entreprise partagées, les validations de données
partagées et la sécurité partagée. Vous pouvez étendre l’interface du serveur
d’applications afin d’offrir à l’application client d’autres possibilités pour appeler
le serveur. Pour plus d’informations sur l’extension de l’interface du serveur,
voir “Extension de l’interface du serveur d’applications” à la page 14-19.
6 Enregistrez, compilez et recensez ou installez le serveur d’applications.
• Lorsque le serveur d’applications utilise DCOM, HTTP, Sockets ou
OLEnterprise comme protocole de communication, il fait office de serveur
Automation et doit être recensé comme tout autre serveur ActiveX ou
COM. Pour plus d’informations sur le recensement d’une application, voir
“Recensement d’une application comme serveur Automation” à la
page 47-6.
• Si vous utilisez MTS, le serveur d’applications doit être une bibliothèque
active plutôt qu’un fichier .EXE. Comme tous les appels COM doivent
transiter par le proxy MTS, vous n’avez pas besoin de recenser le serveur
d’applications. Par contre, vous l’installez avec MTS. Pour plus
d’informations sur l’installation des bibliothèques avec MTS, voir
“Installation des objets MTS dans un paquet MTS” à la page 50-23.
• Lorsque le serveur d’applications utilise CORBA, le recensement est
facultatif. Si vous souhaitez que les applications client utilisent la liaison
dynamique à votre interface, vous devez installer l’interface du serveur
dans le référentiel d’interfaces. De plus, si vous souhaitez que les
applications client démarrent le serveur d’applications lorsqu’il n’est pas
encore exécuté, ce dernier doit être recensé avec l’OAD (Object Activation
Daemon). Pour plus d’informations sur le recensement d’un serveur
CORBA, voir “Recensement d’interfaces serveur” à la page 28-9.
7 Si votre serveur d’applications n’utilise pas DCOM, vous devez installer le
logiciel runtime qui reçoit les messages client, instancie le module de données
distant et trie les appels d’interface.
• Pour le protocole TCP/IP Sockets, il s’agit d’une application de répartition
de sockets, Scktsrvr.exe.
Configuration de TRemoteDataModule
Pour ajouter un composant TRemoteDataModule dans votre application, choisissez
Fichier|Nouveau et sélectionnez Module de données distant dans la page Multi-
niveaux de la boîte de dialogue Nouveaux éléments. L’expert Module de
données distant apparaît.
Vous devez fournir un nom de classe pour votre module de données distant. Il
s’agit du nom de base d’un descendant de TRemoteDataModule que votre
application crée. Il s’agit aussi du nom de base de l’interface de cette classe. Par
exemple, si vous spécifiez le nom de classe MyDataServer, l’expert crée une
nouvelle unité en déclarant TMyDataServer, un descendant de
TRemoteDataModule, qui implémente IMyDataServer, un descendant de IAppServer.
Remarque Vous pouvez ajouter vos propres propriétés et méthodes à la nouvelle interface.
Pour plus d’informations, voir “Extension de l’interface du serveur
d’applications” à la page 14-19.
Si vous créez une bibliothèque de liaison dynamique (Active Library), vous
devez spécifier le modèle threading dans l’expert Module de données distant.
Vous pouvez choisir Thread Unique, Thread Appartement, Thread Libre ou Les
deux.
• Si vous choisissez Thread Unique, COM fait en sorte qu’une seule requête
client soit traitée à un moment donné. Aucune requête client ne peut entrer en
conflit avec une autre.
• Si vous choisissez Thread Appartement, COM fait en sorte que toute instance
de votre module de données distant traite une seule requête à un moment
donné. Lorsque vous écrivez du code dans une bibliothèque Thread
Appartement, vous devez prévenir les conflits de thread si vous utilisez des
variables globales ou des objets non contenus dans le module de données
distant. C’est le modèle recommandé si vous utilisez des ensembles de
données BDE. (Veuillez noter que vous aurez besoin d’un composant session
dont la propriété AutoSessionName vaut True pour gérer les problèmes de
threading sur les ensembles de données BDE)
• Si vous choisissez Thread Libre, votre application peut recevoir des requêtes
client simultanées sur plusieurs threads. Vous devez faire en sorte que votre
application soit compatible avec les threads. Comme plusieurs clients peuvent
simultanément accéder à votre module de données distant, vous devez
protéger vos données d’instance (propriétés, objets contenus, etc.) ainsi que les
variables globales. C’est le modèle recommandé si vous utilisez des ensembles
de données ADO.
• Si vous choisissez Les deux, votre bibliothèque fonctionne de la même façon
que lorsque vous choisissez Thread Libre, à la différence que tous les rappels
(appels vers les interfaces client) sont automatiquement sérialisés.
Si vous créez un fichier .EXE, vous devez spécifier le type d’instanciation à
utiliser. Vous pouvez choisir Instance unique ou Instance multiple (l’instanciation
interne ne s’applique que si le code client fait partie du même espace de
processus.)
• Si vous choisissez Instance unique, chaque connexion client lance sa propre
instance du fichier exécutable. Ce processus instancie une seule instance du
module de données distant, qui est dédié à la connexion client.
• Si vous choisissez Instance multiple, une seule instance de l’application
(processus) instancie tous les modules de données distants créés pour les
clients. Chaque module de données distant est dédié à une seule connexion
client, mais ils partagent tous le même espace de processus.
Configuration de TMTSDataModule
Pour ajouter un composant TMTSDataModule dans votre application, choisissez
Fichier|Nouveau et sélectionnez Module de données MTS dans la page Multi-
niveaux de la boîte de dialogue Nouveaux éléments. L’expert Module de
données MTS apparaît.
Vous devez fournir un nom de classe pour votre module de données distant. Il
s’agit du nom de base d’un descendant de TMTSDataModule que votre
application crée. Il s’agit aussi du nom de base de l’interface de cette classe. Par
exemple, si vous spécifiez le nom de classe MyDataServer, l’expert crée une
nouvelle unité en déclarant TMyDataServer, un descendant de TMTSDataModule,
qui implémente IMyDataServer, un descendant de IAppServer.
Remarque Vous pouvez ajouter vos propres propriétés et méthodes à votre nouvelle
interface. Pour plus d’informations, voir “Extension de l’interface du serveur
d’applications” à la page 14-19.
Configuration de TCorbaDataModule
Pour ajouter un composant TCorbaDataModule dans votre application, choisissez
Fichier|Nouveau et sélectionnez Module de données CORBA dans la page
Multi-niveau de la boîte de dialogue Nouveaux éléments. L’expert Module de
données CORBA apparaît.
Vous devez fournir un nom de classe pour votre module de données distant. Il
s’agit du nom de base d’un descendant de TCorbaDataModule que votre
application crée. Il s’agit aussi du nom de base de l’interface de cette classe. Par
exemple, si vous spécifiez le nom de classe MyDataServer, l’expert crée une
nouvelle unité en déclarant TMyDataServer, un descendant de TCorbaDataModule,
qui implémente IMyDataServer, un descendant de IAppServer.
Remarque Vous pouvez ajouter vos propres propriétés et méthodes à votre nouvelle
interface. Pour plus d’informations sur l’ajout d’éléments à l’interface de votre
module de données, voir “Extension de l’interface du serveur d’applications” à la
page 14-19.
L’expert module de données CORBA vous permet de spécifier comment votre
application serveur crée les instances du module de données distant. Vous
pouvez choisir entre le mode partagé ou instance par client.
• Lorsque vous choisissez le mode partagé, votre application crée une instance
unique du module de données distant qui gère toutes les requêtes client. Ce
modèle est traditionnellement utilisé dans le développement CORBA.
• Lorsque vous choisissez le mode une instance par client, une nouvelle instance
du module de données distant est créée pour chaque connexion client. Cette
instance persiste jusqu’à ce que le délai d’inactivité soit écoulé sans message
de la part du client. Cela permet certes au serveur de libérer les instances
lorsqu’elles ne sont plus utilisées par les clients, mais présente le risque que le
serveur soit libéré prématurément si le client n’utilise pas l’interface du
serveur pendant une longue période.
Remarque Contrairement au modèle d’instanciation des serveurs COM, où est déterminé le
nombre d’instances du processus qui sont exécutées, dans le modèle CORBA,
l’instanciation détermine le nombre d’instances de votre objet qui sont créées.
Elles sont toutes créées dans une seule instance de l’exécutable serveur.
Outre le modèle d’instanciation, vous devez spécifier le modèle threading dans
l’expert Module de données CORBA. Vous pouvez choisir Monothread ou
Multithread.
• Si vous choisissez Monothread, chaque instance du module de données distant
est assurée de ne recevoir qu’une requête client à un moment donné. Vous
pouvez accéder en sécurité aux objets contenus dans votre module de données
distant. Toutefois, vous devez prévenir les conflits de thread lorsque vous
utilisez des variables globales ou des objets non contenus dans le module de
données distant.
• Si vous choisissez Multithread, chaque connexion client dispose de son
propre thread. Toutefois, votre application peut être appelée par plusieurs
clients simultanément, chacun sur un thread différent. Vous devez prévenir
l’accès simultané aux données d’instance ainsi qu’à la mémoire globale.
L’écriture de serveurs multithreads est délicate lorsque vous utilisez une
instance partagée du module de données distant car vous devez protéger
toute l’utilisation des objets contenus dans le module.
7 Créez l’application client ainsi que vous le feriez pour toute autre application
de bases de données. Vous voudrez probablement utiliser les fonctions
spéciales des ensembles de données client qui interagissent avec les
composants fournisseur sur le serveur d’applications. Elles sont décrites par
“Utilisation d’un ensemble de données client avec un fournisseur de données”
à la page 24-16.
Courtage de connexions
Si votre application client peut choisir parmi plusieurs serveurs, vous pouvez
utiliser un courtier d’objets pour localiser un système serveur disponible. Le
courtier d’objets gère une liste de serveurs disponibles pour le composant
connexion. Lorsque le composant connexion a besoin de se connecter à un
serveur d’applications, il demande au courtier d’objets un nom d’ordinateur (ou
une adresse IP, un nom d’hôte, une URL). Le courtier fournit un nom puis le
composant connexion établit la connexion. Si le nom fourni ne fonctionne pas
(par exemple si le serveur n’est pas opérationnel), le courtier fournit un autre
nom et répète l’opération jusqu’à ce que la connexion soit établie.
Une fois que le composant connexion a établi une connexion avec un nom fourni
par le courtier, il enregistre ce nom en tant que valeur de la propriété appropriée
(ComputerName, Address, Host, RemoteHost ou URL). Si le composant connexion
ferme la connexion puis a besoin de l’ouvrir à nouveau, il utilise cette valeur de
propriété et ne demande un nouveau nom au courtier que si la connexion
échoue.
Pour utiliser un courtier d’objets, spécifiez la propriété ObjectBroker de votre
composant connexion. Lorsque la propriété ObjectBroker est initialisée, le
composant connexion n’enregistre pas la valeur de ComputerName, Address, Host,
RemoteHost ou URL.
Remarque N’utilisez pas la propriété ObjectBroker avec des connexions OLEnterprise ni avec
des connexions CORBA. Chacun de ces deux protocoles a son propre service de
courtage.
Connexion au serveur
Pour localiser le serveur d’applications et vous y connecter, vous devez d’abord
initialiser les propriétés du composant connexion pour identifier le serveur
d’applications. Ce processus est décrit dans “Connexion au serveur
d’applications” à la page 14-22. De plus, avant d’ouvrir la connexion, tous les
ensembles de données client qui utilisent le composant connexion pour
communiquer avec le serveur d’applications doivent l’indiquer en initialisant leur
propriété RemoteServer.
La connexion est automatiquement ouverte lorsque les ensembles de données
client essaient d’accéder au serveur d’applications. Par exemple, l’initialisation à
True de la propriété Active de l’ensemble de données client ouvre la connexion,
pour autant que la propriété RemoteServer ait été définie.
B a se d e
d on né es
d istan te
N a viga te ur
• Les contrôles ActiveX doivent être téléchargés sur le navigateur pour agir en
tant que serveur en processus. Il s’en suit que les clients utilisant l’approche
ActiveX exigent beaucoup plus de mémoire que les clients d’une application
basée sur html.
• L’approche InternetExpress peut s’intégrer à d’autres pages HTML. Un client
ActiveX doit être exécuté dans une fenêtre à part.
• L’approche InternetExpress utilise HTTP standard, excluant donc les
problèmes de coupe-feu auxquels sont confrontées les applications ActiveX.
• L’approche ActiveX autorise une plus grande souplesse dans la façon de
programmer votre application. Vous n’êtes pas limité par les capacités des
bibliothèques javascript. Les ensembles de données client utilisés dans
l’approche ActiveX exposent plus de fonctionnalités (filtres, fourchettes,
globalisation, paramètres facultatifs, lecture différée des BLOB ou des détails
imbriquées, etc.) que les navigateurs XML utilisés par l’approche
InternetExpress.
Attention Votre application client Web risque d’apparaître et de se comporter de manière
différente selon le navigateur qui l’affiche. Testez-la avec les navigateurs dont se
serviront vos utilisateurs finals.
Remarque Quand le courtier XML fournit un paquet de données à un autre composant (ou
que vous appelez RequestRecords), il reçoit un événement OnRequestRecords. Vous
pouvez utiliser cet événement pour fournir votre propre chaîne XML au lieu du
paquet de données du serveur d’applications. Par exemple, vous pouvez lire le
paquet de données XML à partir du serveur d’applications à l’aide de
GetXMLRecords, puis le modifier avant de le fournir à la page Web.
Vous pouvez spécifier les composants générant chaque partie de la page Web
avec l’éditeur de pages Web. Affichez l’éditeur de pages Web en double-cliquant
sur le composant page Web ou, dans l’inspecteur d’objets, en cliquant sur le
bouton points de suspension situé à côté de la propriété WebPageItems.
Les composants que vous ajoutez dans l’éditeur de pages Web génèrent le code
HTML qui remplace une des balises transparentes pour HTML du modèle par
défaut du producteur de page MIDAS. Ces composants constituent la valeur de
la propriété WebPageItems. Après avoir inséré les composants dans l’ordre qui
vous convient, vous pouvez personnaliser le modèle pour ajouter votre propre
code HTML ou modifier les balises par défaut.
• TQueryForm génère une fiche HTML pour afficher ou lire les valeurs définies
par l’application. Par exemple, vous pouvez utiliser cette fiche pour afficher et
soumettre des valeurs de paramètres.
Les éléments que vous ajoutez à TQueryForm affichent les valeurs définies par
l’application (TQueryFieldGroup). Ils peuvent également constituer un jeu de
boutons soumettant ou réinitialisant ces valeurs (TQueryButtons). Chacun de
ces éléments contient des sous-éléments qui représentent une valeur ou un
bouton individuel. Vous pouvez également ajouter une grille de disposition à
une fiche de requête comme vous le faites à une fiche de données.
La partie inférieure de l’éditeur de pages Web affiche le code HTML généré et
vous permet de voir ce qu’il donne dans un navigateur (IE4).
• Si vous partagez une feuille de style avec d’autres applications, vous pouvez
fournir les définitions de style dans la valeur de la propriété StylesFile du
producteur de page MIDAS et non dans la propriété Styles. Les éléments Web
individuels peuvent continuer à faire référence aux styles via la propriété
StyleRule.
Autre propriété commune des éléments Web : la propriété Custom. Custom est un
jeu d’options que vous ajoutez à la balise HTML générée. HTML définit un jeu
d’options différent pour chaque type de balise. La référence de la VCL donne un
exemple des options possibles pour la propriété Custom de la plupart des
éléments Web. Pour plus d’informations sur ces options, reportez-vous à un
guide de référence HTML.
Les erreurs de mise à jour peuvent être traitées par le serveur d’applications ou
par le client. Les serveurs d’applications doivent gérer toutes les erreurs de mise
à jour qui ne nécessitent pas d’interaction avec l’utilisateur pour être résolues.
Quand le serveur d’applications ne peut résoudre une condition d’erreur, il
stocke une copie temporaire de l’enregistrement posant problème. Quand le
traitement des enregistrements est terminé, le serveur d’applications renvoie à
l’ensemble de données client le nombre d’erreurs ayant eu lieu et copie les
enregistrements non résolus dans un paquet de données résultat qu’il envoie au
client pour que celui-ci termine la réconciliation.
Les gestionnaires d’événements de tous les événements du fournisseur reçoivent
les mises à jour sous la forme d’un ensemble de données client. Si le gestionnaire
d’événement ne traite que certains types de mise à jour, vous pouvez filtrer
l’ensemble de données en vous basant sur le type de mise à jour de
l’enregistrement afin que le gestionnaire d’événement n’ait pas besoin de
parcourir des enregistrements qu’il n’utilise pas. Pour ce faire, définissez la
valeur de la propriété StatusFilter de l’ensemble de données client.
Remarque Les applications doivent proposer des fonctions supplémentaires quand les mises
à jour sont dirigées vers un ensemble de données qui représente plusieurs tables.
Pour des détails sur la manière de procéder, voir “Application des mises à jour à
des ensembles de données représentant plusieurs tables” à la page 15-10.
Vous pouvez avoir besoin d’un contrôle encore plus précis. Par exemple, dans
l’instruction précédente, vous pouvez empêcher que le champ EMPNO ne soit
modifié en le retirant de la clause UPDATE et enlever les champs TITLE et
DEPT de la clause WHERE pour empêcher des conflits de mise à jour quand
d’autres applications ont modifié les données. Pour spécifier la clause dans
laquelle un champ spécifique apparaît, utilisez la propriété ProviderFlags.
ProviderFlags est un ensemble qui peut inclure les valeurs du tableau suivant :
Vous pouvez également utiliser cet événement pour appliquer vous-même les
mises à jour ou pour filtrer et rejeter les mises à jour. Le gestionnaire
d’événement BeforeUpdateRecord vous permet de signaler au composant de
résolution qu’une mise à jour a déjà été gérée et qu’elle ne doit pas être
appliquée. Le mécanisme de résolution passe cet enregistrement sans le
considérer comme une erreur de mise à jour. Cet événement vous permet
d’appliquer les mises à jour dans une procédure stockée (qui ne peut être mise à
jour automatiquement), en permettant au fournisseur de ne pas effectuer le
traitement automatique une fois l’enregistrement mis à jour dans le gestionnaire
d’événement.
• NOT NULL UNIQUE, afin de garantir qu’une colonne contient une valeur et
que cette valeur n’existe pas dans cette colonne pour un autre enregistrement.
• CHECK, afin de garantir que la valeur d’une colonne se trouve dans un
intervalle spécifié ou qu’elle appartient à une plage limitée de valeurs autorisées.
• CONSTRAINT, une contrainte portant sur la table s’appliquant à plusieurs
colonnes.
• PRIMARY KEY, pour désigner une ou plusieurs colonnes comme clé primaire
jouant un rôle dans l’indexation.
• FOREIGN KEY, pour désigner une ou plusieurs colonnes dans une table en
référençant une autre.
Remarque Cette liste n’est pas exhaustive. Votre serveur de bases de données peut gérer
certaines ou toutes les contraintes précédentes, ainsi que d’autres. Pour
davantage d’informations sur les contraintes qu’il gère, consultez la
documentation de votre serveur.
Les contraintes d’un serveur de base de données prennent la place de
nombreuses vérifications effectuées auparavant par les applications classiques de
bases de données de bureau. Vous pouvez tirer profit des contraintes définies
par le serveur dans vos applications de bases de données multiniveaux sans
avoir à reproduire les contraintes dans le code du serveur d’applications ou dans
celui de l’application client.
Si le fournisseur utilise un ensemble de données BDE, sa propriété Constraints
vous permet de reproduire et d’appliquer les contraintes du serveur aux données
transmises ou reçues par les applications client. Si Constraints a la valeur True
(cas par défaut), les contraintes du serveur sont reproduites sur le client et
affectent les tentatives de modification des données par les clients.
Attention Avant que le serveur d’applications ne puisse transférer à l’application client les
informations relatives aux contraintes, il doit lire ces informations sur le serveur
de bases de données. Pour importer les contraintes de base de données du
serveur, utilisez l’explorateur SQL pour importer les contraintes du serveur de
base de données et les expressions par défaut dans le dictionnaire de données.
Les contraintes et les expressions par défaut du dictionnaire de données sont
automatiquement proposées par le serveur d’applications aux ensembles de
données client.
Il est parfois nécessaire de ne pas appliquer les contraintes du serveur aux
données envoyées à une application client. Ainsi quand une application client
reçoit les données en paquets et autorise la modification locale des données
avant la lecture de tous les enregistrements, il peut être nécessaire de désactiver
certaines des contraintes du serveur qui risquent d’être déclenchées à cause d’un
ensemble de données temporairement incomplet. Pour empêcher la réplication
des contraintes du serveur par l’ensemble de données client, affectez la valeur
False à Constraints. De toute façon, les ensembles de données client peuvent
désactiver ou activer les contraintes en utilisant les méthodes DisableConstraints et
EnableConstraints. Pour davantage d’informations sur l’activation et la
désactivation des contraintes par les ensembles de données client, voir “Gestion
des contraintes” à la page 24-22.
Remarque Gardez à l’esprit qu’il est facultatif de créer des sessions supplémentaires, sauf si
une application exécute des requêtes simultanées sur une base de données ou s’il
s’agit d’une application multithread.
Suivez les étapes ci-dessous pour activer la création dynamique d’un composant
session à l’exécution :
1 Déclarez un pointeur sur une variable TSession.
2 Instanciez une nouvelle session en appelant le constructeur Create. Le
constructeur définit une liste vide de composants base de données pour la
session, crée une liste de callbacks BDE pour la session, met la propriété
KeepConnections à True et ajoute la session à la liste des sessions gérée par le
composant liste de sessions.
3 Affectez à la propriété SessionName de la nouvelle session un nom unique.
Cette propriété est utilisée pour associer les composants base de données à la
session. Pour plus d’informations sur la propriété SessionName, voir
“Dénomination d’une session” à la page 16-4.
4 Activez la session et modifiez éventuellement ses propriétés.
Remarque Ne supprimez jamais la session par défaut.
La création et l’ouverture de sessions peuvent aussi être gérées au moyen de la
méthode OpenSession du composant TSessionList. L’utilisation de OpenSession
présente moins de risques que l’appel de Create, car OpenSession ne crée une
session que si celle-ci n’existe pas. Pour plus d’informations sur la méthode
OpenSession, voir “Gestion de plusieurs sessions” à la page 16-17.
Le code suivant crée un nouveau composant session, lui affecte un nom et ouvre
la session pour réaliser des opérations de base de données (non illustrées ici). A
la fin des opérations, il est détruit par un appel en direction de la méthode Free.
var
SecondSession: TSession;
begin
SecondSession := TSession.Create;
with SecondSession do
try
SessionName := 'SecondSession';
KeepConnections := False;
Open;
...
finally
SecondSession.Free;
end;
end;
Après avoir activé une session, vous pouvez ouvrir ses connexions de base de
données en appelant la méthode OpenDatabase.
Pour les composants session que vous placez dans un module de données ou
dans une fiche, le fait de mettre Active à False quand les bases de données ou les
ensembles de données sont ouverts provoque leur fermeture. Lors de l’exécution,
cette fermeture peut provoquer l’appel d’événements associés.
Remarque Vous ne pouvez pas mettre à False la propriété Active de la session par défaut au
moment de la conception. Bien que cela soit déconseillé, il est possible de fermer
la session par défaut à l’exécution.
Au moment de la conception, utilisez l’inspecteur d’objets pour mettre Active à
False afin de désactiver tous les accès de base de données d’une session par une
simple modification de propriété. Lors de la conception d’une application, cette
opération permet d’inhiber provisoirement les exceptions provoquées par
l’indisponibilité momentanée d’une base de données distante.
Vous pouvez utiliser les méthodes Open et Close d’une session pour activer ou
désactiver des sessions autres que la session par défaut au moment de
l’exécution. Par exemple, la simple ligne de code suivante ferme toutes les bases
de données et tous les ensembles de données ouverts pour une session :
Session1.Close;
Ce code affecte la valeur False à la propriété Active de Session1. Lorsque la
propriété Active d’une session est à False, toute tentative ultérieure de la part de
l’application pour ouvrir une base ou un ensemble de données a pour effet de
réinitialiser Active à True et d’appeler le gestionnaire d’événement OnStartup de
la session, s’il est défini. Il vous est également possible de coder la réactivation
de la session à l’exécution. Le code suivant réactive Session1 :
Session1.Open;
Remarque Si une session est active, vous pouvez aussi ouvrir et fermer des connexions de
base de données particulières. Pour plus d’informations, voir “Fermeture d’une
connexion de base de données” à la page 16-8.
OpenDatabase rend une session active si elle ne l’est pas déjà, puis détermine si le
nom de base de données spécifié correspond à la propriété DatabaseName d’un
composant base de données de cette session. Si le nom spécifié ne correspond à
aucun composant base de données existant, OpenDatabase crée un composant
base de données temporaire et lui donne ce nom. Chaque appel à OpenDatabase
incrémente d’une unité le nombre de références à la base de données. Tant que
ce nombre de références est supérieur à 0, la base de données est ouverte. Pour
finir, OpenDatabase appelle la méthode Open du composant base de données pour
établir la connexion au serveur.
Les instructions suivantes utilisent AddAlias pour ajouter un nouvel alias pour
accéder à un serveur InterBase dans le cadre de la session par défaut :
var
AliasParams: TStringList;
begin
AliasParams := TStringList.Create;
try
with AliasParams do begin
Add('OPEN MODE=READ');
Add('USER NAME=TOMSTOPPARD');
Add('SERVER NAME=ANIMALS:/CATS/PEDIGREE.GDB');
end;
Session.AddAlias('CATS', 'INTRBASE', AliasParams);
...
finally
AliasParams.Free;
end;
end;
L’instruction suivante utilise AddStandardAlias pour créer un nouvel alias pour
accéder à une table Paradox :
AddStandardAlias('MYDBDEMOS', 'C:\TESTING\DEMOS\', 'Paradox');
Les instructions suivantes utilisent ModifyAlias pour provoquer le changement du
paramètre OPEN MODE en READ/ WRITE pour l’alias CATS dans la session
par défaut :
var
List: TStringList;
begin
List := TStringList.Create;
with List do begin
Clear;
Add('OPEN MODE=READ/WRITE');
end;
Session.ModifyAlias('CATS', List);
List.Free;
...
DatabaseCount est une propriété de type entier qui indique le nombre de bases de
données actuellement actives associées à une session. Ce nombre évolue au fur et
à mesure des ouvertures et fermetures de connexions pendant la durée de la
session. Par exemple, si la propriété KeepConnections de la session est à False et
que, lors de l’exécution, tous les composants base de données sont créés au fur
et à mesure des besoins, alors, à chaque fois qu’une nouvelle base de données
est ouverte, DatabaseCount augmente d’une unité. De même, à chaque fois qu’une
base de données est fermée, DatabaseCount diminue d’une unité. Si DatabaseCount
est de valeur nulle, c’est qu’aucun composant base de données n’est actuellement
actif pour la session.
DatabaseCount est généralement utilisée conjointement à la propriété Databases
pour effectuer des actions communes à tous les composants base de données
actifs.
Le code suivant met à True la propriété KeepConnection de chaque base de
données active dans la session par défaut :
var
MaxDbCount: Integer;
begin
with Session do
if (DatabaseCount > 0) then
for MaxDbCount := 0 to (DatabaseCount - 1) do
Databases[MaxDbCount].KeepConnection := True;
end;
var
Passwrd: String;
begin
Passwrd := InputBox('Enter password', 'Password:', '');
Session.AddPassword(Passwrd);
try
Table1.Open
except
ShowMessage('Could not open table!');
Application.Terminate;
end;
end;
La fonction InputBox ci-dessus n'est utilisée qu'à titre de démonstration. Dans une
application réelle, utilisez des utilitaires de saisie de mot de passe qui masquent
le mot de passe lorsqu'il est entré, comme la fonction PasswordDialog ou une fiche
personnalisée. Sur une fiche personnalisée de saisie de mot de passe, utilisez un
composant TEdit en affectant un astérisque ("*") au paramètre PasswordChar.
Le bouton Ajouter de la boîte de dialogue de la fonction PasswordDialog produit
le même effet que la méthode AddPassword.
if PasswordDialog(Session) then
Table1.Open
else
ShowMessage('No password given, could not open table!');
end;
Remarque Il faut appeler AddPassword pour spécifier un ou plusieurs mots de passe à utiliser
(un à la fois) lors de l’accès à des fichiers protégés par mot de passe. Sinon,
lorsque votre application tente d’ouvrir une table Paradox protégée par mot de
passe, une boîte de dialogue demande à l’utilisateur de saisir un mot de passe.
Important Quand vous placez un composant session, vous devez définir sa propriété
SessionName par une valeur unique pour qu’elle n’entre pas en conflit avec la
propriété SessionName de la session par défaut.
Le fait de créer un composant session au moment de la conception présuppose
que le nombre de threads (et donc de sessions) requis par l’application est
statique (déterminé à l’avance). Toutefois, le plus souvent, les sessions de votre
application devront être créées de façon dynamique. Pour créer dynamiquement
des sessions, il suffit d’appeler la fonction globale Sessions.OpenSession à
l’exécution.
Sessions.OpenSession accepte un paramètre : le nom de la session unique par
rapport aux autres noms de session de l’application. Le code suivant crée
dynamiquement une nouvelle session, puis l’active à partir d’un nom unique
généré :
Sessions.OpenSession('RunTimeSession' + IntToStr(Sessions.Count + 1));
Cette instruction génère un nom unique pour la nouvelle session en récupérant
le nombre actuel de sessions puis en ajoutant un à cette valeur. Remarquez que
cet exemple de code ne fonctionnera pas si vous créez et détruisez des sessions
de façon dynamique à l’exécution. Néanmoins, cet exemple montre comment
utiliser les propriétés et les méthodes de Sessions pour gérer plusieurs sessions.
Sessions est une variable de type TSessionList qui est automatiquement instanciée
dans une application de base de données. Les propriétés et les méthodes Sessions
sont utilisées pour garder la trace des sessions dans une application de base de
données multithread. Le tableau 16.2 dresse la liste des propriétés et des
méthodes du composant TSessionList :
except
TempDatabase.Free;
raise;
end;
end;
Le fragment de code suivant illustre comment cette fonction peut être appelée à
l’exécution afin de créer un composant base de données pour la session par
défaut :
var
MyDatabase: array [1..10] of TDatabase;
MyDbCount: Integer;
begin
{ Initialise MyDbCount ultérieurement }
MyDbCount := 1;
ƒ
{ Puis crée un composant base de données à l’exécution }
begin
MyDatabase[MyDbCount] := RunTimeDbCreate('MyDb' + IntToStr(MyDbCount), '');
Inc(MyDbCount);
end;
ƒ
end;
Remarque Lorsqu’un composant base de données n’est pas connecté à un serveur et qu’une
application tente d’ouvrir un ensemble de données associé à un composant base
de données, la méthode Open du composant base de données est appelée pour
établir la connexion. Si l’ensemble de données n’est pas associé à un composant
base de données existant, un composant base de données temporaire est créé et
utilisé pour établir la connexion.
Une fois établie, la connexion de base de données est conservée tant qu’il y a au
moins un ensemble de données actif. Si aucun ensemble de données n’est plus
actif, l’abandon ou le maintien de la connexion dépend de la propriété
KeepConnection du composant base de données.
KeepConnection détermine si votre application doit maintenir la connexion à une
base de données même si tous les ensembles de données associés à cette base
sont fermés. Si elle est à True, la connexion est maintenue. Pour les connexions
vers des serveurs de base de données distants, ou pour les applications qui
ouvrent et ferment fréquemment des ensembles de données, il est préférable que
KeepConnection soit à True afin de réduire le trafic sur le réseau et d’accélérer
votre application. Si elle est à False (la valeur par défaut), une connexion est
fermée dès qu’il n’y a plus d’ensemble de données actif utilisant la base de
données. Si un ensemble de données (qui utilise la base de données) est
ultérieurement ouvert, la connexion doit être à nouveau établie et initialisée.
Utilisation de ODBC
Une application peut utiliser les sources de données ODBC telles que Btrieve.
Une connexion de pilote ODBC nécessite :
• Un pilote ODBC fourni par votre revendeur.
• Le gestionnaire Microsoft de pilote ODBC.
• L’administrateur BDE.
Pour définir un alias BDE pour une connexion de pilote ODBC, utilisez
l’administrateur BDE. Pour plus d’informations, voir le fichier d’aide en ligne de
l’administrateur BDE.
Pour que l’ensemble de résultats produit par l’instruction SQL soit disponible
après l’appel à la méthode Execute, fournissez au préalable un composant ensemble
de données (par exemple un composant TTable). Fournissez une variable de type
hDBICur (un handle sur un curseur BDE). (Pour utiliser ce type de données, l’unité
contenant l’appel à la méthode Execute doit inclure “BDE”, l’unité enveloppe BDE,
dans sa section Uses.) Passez cette variable hDBICur (dé-référencée) dans le
paramètre Cursor de la méthode Execute. Une fois que la méthode Execute est
appelée, affectez le handle du curseur BDE à la propriété Handle du composant
ensemble de données. (Le composant ensemble de données doit être transtypé en
TDBDataSet pour cette affectation, car la propriété Handle est en lecture seule dans
toutes les classes liées aux ensembles de données sauf dans TDBDataSet.)
L’exemple de routine ci-après exécute une instruction SELECT à l’aide de la
méthode Execute. L’ensemble de résultats produit par cette action est accessible
via un composant TTable nommé Table1.
procedure TDataForm.SELECT_NoParamsButtonClick(Sender: TObject);
var
SQLstmt: String;
Cursor: hDBICur;
begin
Database1.Connected := True;
SQLstmt := 'SELECT Company, State ' +
'FROM Customer ' +
'ORDER BY State, Company';
Database1.Execute(SQLstmt, nil, False, @Cursor);
Table1.Close;
(Table1 as TDBDataSet).Handle := Cursor;
end;
Si le composant ensemble de données était utilisé auparavant pour représenter
un autre ensemble de résultats SQL, appelez sa méthode Close pour désactiver
correctement ce curseur de données avant d’affecter le nouveau au composant
ensemble de données.
L’ensemble de résultats renvoyé via le paramètre Cursor de la méthode Execute
est toujours en lecture seule.
La figure 18.1 illustre les relations hiérarchiques existant entre les composants
ensemble de données :
Figure 18.1 Hiérarchie des composants ensemble de données sous Delphi
TDataSet
TADOCommand TNestedTable
TADODataSet TDBDataSet
TADOQuery TTable
TADOStoredProc TQuery
TStoredProc
Tableau 18.1 Valeurs possibles pour la propriété State des ensembles de données
Valeur Etat Signification
dsInactive Inactif L’ensemble de données est fermé. Ses données sont
indisponibles.
dsBrowse Visualisation L’ensemble de données est ouvert. Ses données sont
visualisables mais ne peuvent être modifiées. C’est l’état par
défaut d’un ensemble de données ouvert.
dsEdit Edition L’ensemble de données est ouvert. La ligne en cours peut
être modifiée.
dsInsert Insertion L’ensemble de données est ouvert. Une nouvelle ligne peut
être insérée.
dsSetKey Indexation S’applique à TTable et TClientDataSet uniquement. L’ensemble
(SetKey) de données est ouvert. Active la définition de portées et de
valeurs clé pour les opérations portant sur des portées et les
opérations GotoKey.
dsCalcFields Champs L’ensemble de données est ouvert. Indique qu’un événement
calculés OnCalcFields est en cours. Interdit toute modification de
(CalcFields) champ non calculé.
dsCurValue CurValue Utilisation interne uniquement.
dsNewValue NewValue Utilisation interne uniquement.
Tableau 18.1 Valeurs possibles pour la propriété State des ensembles de données
Valeur Etat Signification
dsOldValue OldValue Utilisation interne uniquement.
dsFilter Filtrage L’ensemble de données est ouvert. Indique qu’une opération
de filtrage est en cours. Un ensemble de données restreint
peut être visualisé, sans qu’aucune donnée ne puisse être
changée.
Remarque A chaque fois que l’état d’un ensemble de données change, l’événement
OnStateChange est appelé pour tous les composants source de données associés.
Pour plus d’informations concernant les composants source de données et sur
OnStateChange, voir “Utilisation des sources de données” à la page 26-6.
Les sections suivantes présentent chacun de ces états en indiquant comment ils
sont définis, leurs relations et l’endroit où chercher d’éventuelles informations
complémentaires.
dsInactive
Open Close
Insert
Append Edit
dsInsert dsBrowse dsEdit
dsSetKey
Dans les fiches de votre application, les contrôles orientés données grille et
navigateur peuvent mettre un ensemble de données à l’état dsInsert si :
• La propriété ReadOnly du contrôle est à False (la valeur par défaut).
• La propriété AutoEdit de la source de données du contrôle est à True.
• CanModify est à True pour l’ensemble de données.
Important Si la propriété ReadOnly des composants TTable est à True, CanModify est à False,
afin d’empêcher la modification des enregistrements. De même, pour les
composants TQuery, si la propriété RequestLive est à False, CanModify a la valeur
False.
Remarque Même si un ensemble de données est à l’état dsInsert, l’insertion d’enregistrements
peut ne pas réussir dans le cas de bases de données SQL, si l’utilisateur de votre
application ne dispose pas des droits d’accès SQL appropriés.
Dans votre code, vous pouvez renvoyer un ensemble de données de l’état
dsInsert à l’état dsBrowse en appelant l’une des méthodes Cancel, Post ou Delete.
Delete et Cancel annulent le nouvel enregistrement. Post tente d’écrire le nouvel
enregistrement dans l’ensemble de données, et si elle réussit, renvoie l’ensemble
de données à l’état dsBrowse. Si Post ne peut écrire l’enregistrement, l’ensemble
de données reste à l’état dsInsert.
Les contrôles orientés données, pour lesquels l’insertion est automatiquement
activée, appellent Post quand l’utilisateur exécute une action qui change la position
du curseur (comme le déplacement vers un autre enregistrement dans une grille).
Pour en savoir plus sur l’insertion et l’ajout d’enregistrements dans un ensemble
de données, voir “Modification des données” à la page 18-24.
Champs calculés
Delphi bascule un ensemble de données en mode dsCalcFields à chaque fois qu’une
application appelle le gestionnaire d’événement OnCalcFields de l’ensemble de
données. Cet état empêche les modifications et les ajouts dans les enregistrements
de l’ensemble de données sauf s’ils s’appliquent aux champs calculés modifiés par
le gestionnaire lui-même. La raison en est que OnCalcFields utilise les valeurs des
autres champs pour dériver celles des champs calculés. Sinon, les changements
des autres champs pourraient invalider les valeurs affectées aux champs calculés.
Quand ce gestionnaire achève son exécution, l’ensemble de données revient à
l’état dsBrowse.
Pour plus d’informations concernant la création de champs calculés et le
gestionnaire OnCalcFields, voir “Utilisation de l’événement OnCalcFields” à la
page 18-30.
Filtrage d’enregistrements
Delphi met un ensemble de données en mode dsFilter à chaque fois qu’une
application appelle le gestionnaire d’événement OnFilterRecord de l’ensemble de
données. Cet état empêche toute modification ou ajout dans les enregistrements
de l’ensemble de données durant le processus de filtrage afin de ne pas
l’invalider. Pour plus d’informations sur le filtrage, voir “Affichage et édition
d’ensembles de données en utilisant des filtres” à la page 18-19.
Quand le gestionnaire OnFilterRecord achève son exécution, l’ensemble de
données revient à l’état dsBrowse.
Eof
La valeur True de Eof indique que le curseur se trouve sans équivoque sur la
dernière ligne de l’ensemble de données. EOF passe à True quand une
application :
• Ouvre un ensemble de données vide.
• Appelle la méthode Last de l’ensemble de données.
• Appelle la méthode Next de l’ensemble de données et que son exécution
échoue (car le curseur se trouve déjà sur la dernière ligne de l’ensemble de
données).
• Appelle SetRange sur une portée ou un ensemble de données vide.
Eof vaut False dans tout autre cas ; vous devez supposer que Eof vaut False sauf
si l’une des conditions ci-dessus est vérifiée et que vous avez testé directement la
valeur de la propriété.
Le test sur Eof se fait généralement dans une condition de boucle pour contrôler
le processus itératif sur des enregistrements d’un ensemble de données. Eof vaut
False si vous ouvrez un ensemble de données contenant plusieurs
enregistrements (ou si vous appelez First). Pour parcourir un à un les
enregistrements d’un ensemble de données, vous devez créer une boucle qui se
termine quand Eof vaut True. A l’intérieur de la boucle, vous devez appeler Next
pour chaque enregistrement de l’ensemble de données. Eof reste à True jusqu’à ce
que Next soit appelée alors que le curseur se trouve déjà sur le dernier
enregistrement.
Bof
La valeur True de la propriété Bof indique que le curseur se trouve sans
équivoque sur la première ligne de l’ensemble de données. Bof est mis à True
lorsqu’une application :
• Ouvre l’ensemble de données.
• Appelle la méthode First de l’ensemble de données.
• Appelle la méthode Prior de l’ensemble de données et que son exécution
échoue (car le curseur se trouve déjà sur la première ligne de l’ensemble de
données).
• Appelle SetRange sur une portée ou un ensemble de données vide.
Bof vaut False dans tout autre cas ; vous devez supposer que Bof vaut False sauf
si l’une des conditions ci-dessus est vérifiée et que vous avez testé directement la
valeur de la propriété.
Comme Eof, Bof peut se trouver dans une condition de boucle pour contrôler un
processus itératif sur des enregistrements d’un ensemble de données. L’exemple
suivant montre l’une des façons de programmer une boucle de traitement
d’enregistrements pour un ensemble de données appelé CustTable:
CustTable.DisableControls; { Speed up processing; prevent screen flicker }
try
while not CustTable.BOF do { Cycle until BOF is True }
begin
{ Process each record here }
ƒ
CustTable.Prior; { BOF False on success; BOF True when Prior fails on first record }
end;
finally
CustTable.EnableControls; { Display new current row in controls }
end;
Marquage d’enregistrements
Outre la possibilité de se déplacer d’un enregistrement à un autre dans un
ensemble de données (ou de se déplacer selon un nombre déterminé
d’enregistrements), il est possible de marquer un emplacement particulier dans
un ensemble de données de façon à y revenir rapidement le moment voulu.
TDataSet et ses descendants implémentent une fonction de définition de signets
qui permet de repérer un enregistrement dans un ensemble de données pour
pouvoir y revenir ultérieurement. Cette fonction se présente sous la forme de la
propriété Bookmark et de cinq méthodes de définition de signets.
La propriété Bookmark indique quel est le signet en cours dans votre application.
Bookmark est une chaîne qui identifie le signet en cours. Tout nouveau signet
ajouté devient le signet en cours.
TDataSet implémente des méthodes virtuelles de gestion des signets. Alors que
ces méthodes garantissent que chaque objet ensemble de données dérivé de
TDataSet renvoie une valeur si une méthode de signet est appelée, les valeurs
renvoyées sont simplement des valeurs par défaut qui n’indiquent pas la
position en cours. Les descendants de TDataSet, comme TBDEDataSet,
réimplémentent les méthodes de signets de façon à ce qu’elles renvoient des
valeurs significatives :
• BookmarkValid permet de déterminer si un signet donné est en cours
d’utilisation.
• CompareBookmarks est utilisée pour tester deux signets et vérifier s’ils sont
identiques.
• GetBookmark alloue un signet en l’associant à la position en cours dans
l’ensemble de données.
• GotoBookmark se positionne sur un signet précédemment créé par GetBookmark
• FreeBookmark restitue un signet qui a été alloué par GetBookmark.
Pour créer un signet, déclarez une variable de type TBookmark dans votre
application, puis appelez GetBookmark pour allouer l’espace de stockage associé à
la variable et définir sa valeur par un emplacement particulier dans l’ensemble
de données. La variable TBookmark est un pointeur (void *).
Création de filtres
Les deux méthodes suivantes permettent de créer un filtre pour un ensemble de
données :
• Spécifiez des conditions de filtre dans la propriété Filter. Filter est
particulièrement utile pour créer et appliquer des filtres à l’exécution.
Les valeurs des champs peuvent aussi être comparées à des littéraux et à des
constantes en utilisant les opérateurs logiques et les opérateurs de comparaison
suivants :
Tableau 18.4 Opérateurs de comparaison et opérateurs logiques pouvant apparaître dans un filtre
Opérateur Signification
< Inférieur
> Supérieur
>= Supérieur ou égal
<= Inférieur ou égal
= Egal
<> Différent
AND Teste si deux instructions sont à True
NOT Vérifie que l’instruction suivante n’est pas à True
OR Vérifie qu’au moins une des deux instructions est à True
Par exemple, les instructions suivantes définissent un filtre qui ignore les
différences majuscules/minuscules lors de la comparaison des valeurs d’un
champ State :
FilterOptions := [foCaseInsensitive];
Filter := '''State'' = ''CA''';
Tableau 18.7 Méthodes des ensembles de données pour éditer des données
Méthode Description
Edit Met l’ensemble de données à l’état dsEdit s’il n’est pas déjà à l’état dsEdit ou
dsInsert.
Append Emet les données en suspens, déplace le curseur à la fin de l’ensemble de
données, puis met ce dernier à l’état dsInsert.
Insert Emet les données en suspens, puis met l’ensemble de données à l’état dsInsert.
Post Tente d’émettre l’enregistrement nouveau ou modifié vers la base de données. Si
l’opération réussit, l’ensemble de données est mis à l’état dsBrowse ; dans le cas
contraire, son état en cours reste inchangé.
Cancel Annule l’opération en cours et met l’ensemble de données à l’état dsBrowse.
Delete Supprime l’enregistrement en cours et met l’ensemble de données à l’état dsBrowse.
Modification d’enregistrements
Un ensemble de données doit être en mode dsEdit pour que l’application puisse
modifier des enregistrements. Dans votre code, vous pouvez utiliser la méthode
Edit pour mettre un ensemble de données en mode dsEdit si la propriété
CanModify de l’ensemble de données, accessible seulement en lecture, est à True.
C’est le cas si les tables sous-jacentes à l’ensemble de données reconnaissent les
droits d’accès en lecture et écriture.
Dans les fiches de votre application, certains contrôles orientés données pourront
mettre automatiquement votre ensemble de données à l’état dsEdit si les
conditions suivantes sont réunies :
• La propriété ReadOnly du contrôle est à False (la valeur par défaut).
• La propriété AutoEdit de la source de données du contrôle est à True.
• La propriété CanModify de l’ensemble de données est à True.
Important Pour les composants TTable dont la propriété ReadOnly vaut True et les
composants TQuery dont la propriété RequestLive vaut False, CanModify est à False
et empêche l’édition des enregistrements.
Remarque Même si un ensemble de données est à l’état dsEdit, la modification
d’enregistrements peut échouer dans le cas d’une base de données SQL si
l’utilisateur de votre application ne dispose pas des droits d’accès SQL appropriés.
Quand un ensemble de données se trouve en mode dsEdit, l’utilisateur peut
modifier toutes les valeurs de champ de l’enregistrement qui apparaît dans les
contrôles orientés données d’une fiche. Les contrôles orientés données, pour
lesquels la modification est activée automatiquement, appellent Post quand
l’utilisateur accomplit une action qui change la position du curseur (comme le
déplacement vers un autre enregistrement dans une grille).
Si vous avez fourni un composant navigateur dans vos fiches, l’utilisateur peut
annuler les modifications en cliquant sur le bouton Annuler du navigateur.
L’annulation des modifications renvoie l’ensemble de données à l’état dsBrowse.
Dans votre code, vous devez valider ou annuler les modifications en appelant les
méthodes appropriées. Les modifications sont validées en appelant Post. Vous les
annulez en appelant Cancel. Les méthodes Edit et Post sont souvent utilisées
conjointement. Considérons l’exemple suivant :
with CustTable do
begin
Edit;
FieldValues['CustNo'] := 1234;
Post;
end;
Dans cet exemple, la première ligne du fragment de code place l’ensemble de
données en mode dsEdit. La ligne suivante affecte la chaîne 1234 au champ
CustNo de l’enregistrement en cours. Pour finir, la dernière ligne écrit (émet)
l’enregistrement vers la base de données.
Remarque Si la propriété CachedUpdates d’un ensemble de données est à True, les
modifications émises sont écrites dans un tampon temporaire. Pour écrire les
modifications en mémoire cache dans la base de données, appelez la méthode
ApplyUpdates de l’ensemble de données. Pour plus d’informations concernant les
mises à jour en mémoire cache, voir chapitre 25, “Manipulation des mises à jour
en mémoire cache”.
Insertion d’enregistrements
Insert ouvre un nouvel enregistrement vide avant l’enregistrement en cours, puis
positionne le curseur sur ce nouvel enregistrement de façon à que les valeurs de
champ puissent être entrées par l’utilisateur ou par le code de votre application.
Quand une application appelle Post (ou ApplyUpdates si les mises à jour en
mémoire cache sont activées), le nouvel enregistrement inséré peut être écrit de
trois façons dans la base de données :
• Pour les tables Paradox ou dBASE indexées, l’enregistrement est inséré dans
l’ensemble de données à une position déterminée par l’index.
• Pour les tables non indexées, l’enregistrement est inséré dans l’ensemble de
données à sa position actuelle.
• Pour les bases de données SQL, l’emplacement physique où a lieu l’insertion
dépend de l’implémentation. Si la table est indexée, l’index est mis à jour avec
les informations du nouvel enregistrement.
Ajout d’enregistrements
Append ouvre un nouvel enregistrement vide à la fin de l’ensemble de données,
en faisant en sorte que l’enregistrement vide devienne l’enregistrement en cours
afin que les valeurs de champ de l’enregistrement puissent être entrées par
l’utilisateur ou par le code de votre application.
Quand une application appelle Post (ou ApplyUpdates si les mises à jour en
mémoire cache sont activées), le nouvel enregistrement ajouté peut être écrit de
trois façons dans la base de données :
• Pour les tables Paradox ou dBASE indexées, l’enregistrement est inséré dans
l’ensemble de données à une position déterminée par l’index.
• Pour les tables non indexées, l’enregistrement est ajouté à la fin de l’ensemble
de données.
• Pour les bases de données SQL, l’emplacement physique où a lieu l’ajout
dépend de l’implémentation. Si la table est indexée, l’index est mis à jour avec
les données du nouvel enregistrement.
Suppression d’enregistrements
Un ensemble de données doit être actif pour que l’application puisse supprimer
des enregistrements. Delete supprime l’enregistrement en cours dans l’ensemble
de données en mettant ce dernier en mode dsBrowse. L’enregistrement qui suit
celui supprimé devient l’enregistrement en cours. Si les mises à jour en mémoire
cache sont activées pour l’ensemble de données, l’enregistrement n’est réellement
supprimé qu’après l’appel de ApplyUpdates.
Si vous avez doté vos fiches d’un composant navigateur, les utilisateurs pourront
supprimer l’enregistrement en cours en cliquant sur le bouton d’effacement.
Dans votre code, vous devez appeler explicitement Delete pour supprimer
l’enregistrement en cours.
Pour une fiche, vous pouvez permettre à l’utilisateur d’annuler les opérations de
modification, d’insertion, et d’ajout en incluant le bouton Annuler dans un
composant navigateur associé à l’ensemble de données, ou bien le code de votre
propre bouton d’annulation.
Si vous utilisez SetFields pour modifier certains champs, et non tous les champs
d’un enregistrement existant, vous pouvez transmettre des valeurs NULL pour
les champs que vous ne voulez pas changer. Si vous ne fournissez pas un
nombre de valeurs correspondant au nombre de champs d’un enregistrement,
SetFields leur affecte la valeur NULL. Les valeurs NULL écrasent les valeurs
existantes de ces champs.
Par exemple, supposons qu’une base de données dispose d’une table COUNTRY
avec les colonnes Name, Capital, Continent, Area et Population. Si un composant
TTable appelé CountryTable, est lié à la table COUNTRY, l’instruction suivante
insère un enregistrement dans la table COUNTRY :
CountryTable.InsertRecord(['Japan', 'Tokyo', 'Asia']);
Cette instruction ne spécifie aucune valeur pour Area et Population, des valeurs
NULL leur sont donc affectées. La table est indexée sur Name, l’enregistrement
est donc inséré à la position alphabétique de “Japan”.
Pour mettre à jour l’enregistrement, l’application peut utiliser le code suivant :
with CountryTable do
begin
if Locate('Name', 'Japan', loCaseInsensitive) then;
begin
Edit;
SetFields(nil, nil, nil, 344567, 164700000);
Post;
end;
end;
Ce code affecte des valeurs aux champs Area et Population, avant de les émettre
dans la base de données. Les trois valeurs NULL agissent comme marqueurs de
remplissage des trois premières colonnes pour indiquer que leur contenu actuel
doit être préservé.
Attention Quand vous utilisez des pointeurs NULL avec SetFields afin de laisser intacte la
valeur de certains champs, il faut transtyper les NULL en void *. Si vous utilisez
un NULL comme paramètre sans effectuer le transtypage, vous affectez une
valeur vierge au champ.
Si AutoCalcFields vaut False, OnCalcFields n’est pas appelé lorsque des champs
individuels sont modifiés dans un enregistrement.
Pendant la durée de l’exécution de OnCalcFields, l’ensemble de données est en
mode dsCalcFields, et vous ne pouvez donc affecter de valeur à un champ que
s’il s’agit d’un champ calculé. L’exécution de OnCalcFields achevée, l’ensemble de
données revient à l’état dsBrowse.
TDataSet
TNestedTable
TClientDataSet TBDEDataSet
TQuery
TDBDataSet TStoredProc
TTable
L’utilisation des mises à jour en mémoire cache et leur coordination avec d’autres
applications accèdant aux données dans un environnement multi-utilisateur
constituent un sujet complexe entièrement abordé au chapitre 25, “Manipulation des
mises à jour en mémoire cache.”
Pour plus d’informations sur l’utilisation d’un ensemble de données client, voir
chapitre 24, “Création et utilisation d’un ensemble de données client”.
Champs dynamiques
Les composants champ générés dynamiquement correspondent au comportement
par défaut. En fait, tous les composants champ d’un ensemble de données sont
créés dynamiquement à chaque fois que vous placez un ensemble de données
dans un module de données, puis l’associez à une base de données et l’ouvrez.
Un composant champ est dynamique s’il est créé automatiquement. Les
composants champ dynamiques sont créés par Delphi en fonction de la structure
physique sous-jacente des colonnes d’une ou de plusieurs tables connectées à un
ensemble de données. Delphi génère un composant champ pour chaque colonne
des requêtes ou des tables sous-jacentes. Le descendant TField créé pour chaque
colonne d’une table de base de données sous-jacente est déterminé par les
informations de type de champ envoyées par le BDE (Borland Database Engine)
ou par le composant fournisseur (pour les applications multiniveaux).
Le type d’un composant champ détermine ses propriétés et la façon dont les
données qui lui sont associées apparaissent dans les contrôles orientés données
d’une fiche. Les champs dynamiques sont temporaires, leur durée est limitée au
moment où l’ensemble de données est ouvert.
Champs persistants
Par défaut, les champs des ensembles de données sont des champs dynamiques.
Leurs propriétés et leur disponibilité sont automatiquement définies et ne
peuvent pas être modifiées. Pour contrôler les propriétés et les événements d’un
champ de façon à pouvoir définir ou modifier la visibilité du champ ou ses
caractéristiques d’affichage (que ce soit à la conception ou à l’exécution), créer de
nouveaux champs à partir des champs existants dans un ensemble de données
ou valider la saisie des données, vous devez créer des champs persistants.
La boîte de dialogue Ajout de champs se referme et les champs que vous avez
sélectionnés apparaissent dans la boîte liste de l’éditeur de champs ; ce sont les
champs persistants. Si l’ensemble de données est actif, vous remarquerez
également que les boutons de navigation Suivant et Dernier au-dessus de la boîte
liste sont activés.
Désormais, à chaque fois que vous ouvrirez l’ensemble de données, Delphi ne
créera plus de composant champ dynamique pour chaque colonne de la base de
données sous-jacente. Au lieu de cela, il ne créera des composants persistants
que pour les champs spécifiés.
A chaque fois que vous ouvrirez l’ensemble de données, Delphi vérifiera que
chacun des champs persistants non calculés est présent ou qu’il peut être créé à
partir des données de la base. Sinon, il provoquera une exception vous
avertissant que le champ n’est pas valide et n’ouvrira pas l’ensemble de données.
Ces types de champs persistants ne servent que pour l’affichage. Les données
qu’ils contiennent au moment de l’exécution ne sont pas conservées, soit parce
qu’elles existent déjà ailleurs dans la base de données, soit parce qu’elles sont
temporaires. La structure physique de la table et des données sous-jacentes de
l’ensemble de données reste de toute façon inchangée.
Pour créer un nouveau composant champ persistant, cliquez avec le bouton droit
de la souris sur la boîte liste de l’éditeur de champs et choisissez Nouveau
champ. La boîte de dialogue Nouveau champ apparaît.
La boîte de dialogue Nouveau champ contient trois boîtes groupe : Propriétés du
champ, Type de champ et Définition de la référence.
La boîte groupe “Type de champ” vous permet de spécifier le type du nouveau
composant champ à créer. Son type par défaut est Données. Si vous choisissez
Référence, les boîtes de saisie Dataset et Champs clé de la boîte groupe
Définition de la référence sont activées. Il est aussi possible de créer des champs
calculés, et si vous travaillez avec un composant TClientDataSet, vous pouvez
même créer des champs CalcInterne.
La boîte groupe Propriétés du champ vous permet d’entrer des informations
générales sur le composant champ. Tapez le nom de champ du composant dans la
boîte de saisie Nom. Le nom que vous saisissez correspond à la propriété
FieldName du composant champ. C’est ce nom que Delphi utilise pour construire
un nom de composant dans la boîte de saisie Composant. Le nom qui s’y affiche
correspond à la propriété Name du composant champ ; il est fourni uniquement à
titre d’information (Name contient l’identificateur vous permettant de faire
référence au composant champ dans le code source). Delphi ne tient pas compte
de ce que vous entrez directement dans la boîte de saisie Composant.
La boîte à options “Type” vous permet de spécifier le type de données du
composant champ. Vous devez obligatoirement indiquer un type de données
pour chaque nouveau composant champ créé. Par exemple, pour afficher une
valeur monétaire à virgule flottante dans un champ, sélectionnez Currency dans
la liste déroulante. La boîte de saisie Taille vous permet de spécifier le nombre
maximum de caractères pouvant être affichés ou entrés dans un champ chaîne,
ou bien la taille des champs Bytes et VarBytes. Taille ne s’utilise pour aucun autre
type de données.
La boîte groupe Définition de la référence ne s’utilise que pour créer des champs
de référence. Pour plus de détails, reportez-vous à “Définition d’un champ de
référence” à la page 19-11.
4 Sélectionnez Référence dans la boîte groupe Type de champ pour activer les
boîtes à options Dataset et Champs clé.
5 Choisissez dans la liste déroulante de la boîte à options “Dataset” l’ensemble
de données sur lequel doit porter la recherche des valeurs de champ.
L’ensemble de référence doit être différent de celui du composant champ lui-
même, sinon une exception de référence circulaire sera provoquée au moment
de l’exécution. En spécifiant un ensemble de données de référence, vous
activez les boîtes à options Clés de référence et Champ résultat.
6 Dans la liste déroulante Champs clé, choisissez dans l’ensemble de données
actif le champ dont les valeurs doivent se correspondre. Pour faire
correspondre plusieurs champs, entrez leur nom directement au lieu de les
choisir dans la liste déroulante. Séparez leur nom par des points-virgules. Si
vous utilisez plusieurs champs, il faut employer des composants champ
persistants.
7 Dans la liste déroulante Clés de référence, choisissez un champ de l’ensemble
de données de référence devant correspondre au champ source spécifié à
l’étape 6. Si vous avez spécifié plusieurs champs clé, il faut spécifier le même
nombre de clés de référence. Pour spécifier plusieurs champs, entrez leur nom
directement. Séparez leur nom par des points-virgules.
8 Dans la liste déroulante Champ résultat, choisissez un champ de l’ensemble
de données de référence à renvoyer comme valeur du champ de référence que
vous êtes en train de créer.
Lorsque vous concevez et exécutez votre application, les valeurs des champs de
référence sont déterminées avant celles des champs calculés. Il est possible de
créer des champs calculés basés sur des champs de référence mais il est
impossible de créer des champs de référence basés sur des champs calculés. Ce
comportement peut être affiné avec la propriété LookupCache Cette propriété
détermine si les valeurs d’un champ de référence sont placées en mémoire cache
lors de la première ouverture d’un ensemble de données ou si elles sont
référencées dynamiquement à chaque modification de l’enregistrement en cours
dans l’ensemble de données.
Mettez LookupCache à True pour cacher les valeurs d’un champ de référence
lorsque la propriété LookupDataSet ne risque aucune modification et que le
nombre de valeurs de référence est faible. La mise en mémoire cache des valeurs
de référence permet d’accélérer les performances, car les valeurs de référence
relatives à chaque ensemble de valeurs de la propriété LookupKeyFields sont
préchargées à l’ouverture de l’ensemble de données. En cas de modification de
l’enregistrement en cours dans l’ensemble de données, l’objet champ peut
localiser sa valeur (Value) dans la mémoire cache, plutôt que d’accéder à
LookupDataSet. Cette amélioration des performances est appréciable si l’ensemble
de données de référence (LookupDataSet) est sur un réseau présentant des temps
d’accès lents.
Astuce Vous pouvez utiliser une mémoire cache de référence pour proposer les valeurs
de référence par programme au lieu d’utiliser un ensemble de données
secondaire. Créez un objet TLookupList à l’exécution et utilisez sa méthode Add
pour le remplir avec les valeurs de référence. Affectez cet objet TLookupList à la
propriété LookupList du champ de référence et affectez la valeur True à sa
propriété LookupCache. Si les autres propriétés de référence du champ ne sont pas
initialisées, le champ utilise la liste de référence spécifiée sans redéfinir ses
valeurs avec celles d’un ensemble de données de référence.
Si chaque enregistrement de l’ensemble de données (DataSet) comporte des
valeurs différentes pour KeyFields, le temps nécessaire à la localisation des
valeurs dans le cache peut être supérieur aux gains de temps obtenus grâce au
placement en mémoire cache. Plus le nombre de valeurs distinctes dans KeyFields
est élevé, plus le temps de traitement passé à localiser des valeurs dans la
mémoire cache augmente.
Si LookupDataSet risque de changer, le fait de placer des valeurs de référence en
mémoire cache peut provoquer des résultats erronés. Appelez RefreshLookupList
pour mettre à jour les valeurs dans la mémoire cache. RefreshLookupList régénère
la propriété LookupList qui contient la valeur de la propriété LookupResultField de
chaque ensemble de valeurs LookupKeyFields.
Si LookupCache est définie à l’exécution, appelez RefreshLookupList pour initialiser
la mémoire cache.
Toutes les propriétés ne sont pas disponibles pour l’ensemble des composants
champ. Par exemple, un composant champ de type TStringField ne peut pas
avoir les propriétés Currency, MaxValue ou DisplayFormat et un composant de
type TFloatField ne peut pas avoir de propriété Size.
Alors que le rôle de la plupart des propriétés est évident, certaines comme
Calculated nécessitent des étapes de programmation supplémentaires. D’autres,
comme DisplayFormat, EditFormat et EditMask sont reliées entre elles ; leur
configuration doit être coordonnée. Pour plus de détails sur l’utilisation des
propriétés DisplayFormat, EditFormat et EditMask, voir “Contrôle ou dissimulation
de la saisie utilisateur” à la page 19-18.
Pour contrôler la focalisation des composants orientés données d’un champ, vous
devez recourir à la méthode FocusControl. Celle-ci place la focalisation sur le
premier contrôle orienté données d’une fiche associé à un champ. Un
gestionnaire d’événement doit faire appel à la méthode FocusControl d’un champ
avant de le valider. Le code ci-dessous montre comment faire appel à la méthode
FocusControl pour le champ Company de la table Customers :
CustomersCompany.FocusControl;
Le tableau suivant dresse la liste des autres méthodes des composants champ et
présente leur utilisation. Pour une liste complète des méthodes et des
informations détaillées sur leur utilisation, voir les entrées relatives à TField et
ses descendants dans le Guide de référence de la bibliothèque de composants visuels.
Tableau 19.7 Méthodes des composants champ
Méthode Utilisation
AssignValue Affecte à une valeur de champ une valeur spécifiée en utilisant une
fonction de conversion basée sur le type du champ.
Clear Efface le champ et met sa valeur à NULL.
GetData Extrait du champ des données non formatées.
IsValidChar Détermine si un caractère saisi par un utilisateur dans un contrôle orienté
données dans le but de définir une valeur est autorisé.
SetData Affecte des données “brutes” au champ.
Cette méthode fonctionne bien pour les valeurs chaîne, mais elle peut nécessiter
un surcroît de programmation pour pouvoir gérer les conversions d’autres types
de données. Heureusement, les composants champ ont des fonctions intégrées
leur permettant de le faire.
Remarque Vous pouvez également utiliser des variants pour accéder aux valeurs des
champs et les définir. Les variants sont un nouveau type de données d’une
grande souplesse. Pour plus de détails sur leur utilisation pour accéder aux
valeurs de champ et les définir, reportez-vous à “Accès à des valeurs par la
propriété d’ensemble de données par défaut” à la page 19-23.
TVarBytesField
TSmallintField
TGraphicField
TBooleanField
TIntegerField
TStringField
TMemoField
TBytesField
TWordField
TFloatField
TTimeField
TBlobField
TDateField
TBCDField
Fonction
AsVariant ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
AsString ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
AsInteger ✓ ✓ ✓ ✓
AsFloat ✓ ✓ ✓ ✓ ✓ ✓ ✓
AsCurrency ✓ ✓ ✓ ✓ ✓ ✓ ✓
AsDateTime ✓
AsBoolean ✓
Dans les autres cas, la conversion est totalement impossible, toute tentative
provoquant une exception.
Vous pouvez utiliser une fonction de conversion comme n’importe quelle
méthode appartenant à un composant : ajoutez le nom de la fonction à la fin du
nom du composant lorsqu’elle apparaît dans une instruction d’affectation. La
conversion a toujours lieu avant l’affectation. Par exemple, l’instruction ci-
dessous convertit la valeur de CustomersCustNo en chaîne et affecte celle-ci au
texte d’un contrôle de saisie :
Edit1.Text := CustomersCustNo.AsString;
A l’inverse, l’instruction suivante affecte le texte d’un contrôle de saisie au
champ CustomersCustNo en tant qu’entier :
MyTableMyField.AsInteger := StrToInt(Edit1.Text);
Si une conversion non supportée est effectuée lors de l’exécution, cela a pour
effet de provoquer une exception.
Utilisation de contraintes
Les composants champ peuvent utiliser des contraintes de serveur SQL. De plus,
vos applications peuvent créer et utiliser des contraintes personnalisées locales à
l’application. Toutes les contraintes sont des règles ou des conditions qui
définissent et imposent des limites sur un intervalle ou une portée de valeurs
stockées dans un champ. Les sections suivantes décrivent comment les
contraintes peuvent être utilisées avec les composants champ.
20
Manipulation des tables
Chapter 20
Astuce Si votre application utilise des composants base de données pour contrôler les
transactions, attribuez à DatabaseName un alias local défini pour le composant
base de données. Pour obtenir de plus amples informations sur les composants
base de données, reportez-vous au chapitre 17, “Connexion aux bases de
données”.
Tableau 20.1 Types de tables reconnus par le BDE à partir des extensions de fichiers
Extension Type de table
Aucune extension Paradox
.DB Paradox
.DBF dBASE
.TXT texte ASCII
Si vos tables Paradox, dBASE et texte ASCII locales utilisent les extensions
décrites dans le tableau 20.1, vous pouvez laisser la propriété TableType à
ttDefault. Sinon, votre application devra définir TableType de façon à ce qu’elle
indique le type de table approprié. Le tableau 20.2 indique les valeurs pouvant
être affectées à TableType :
Recherche d’enregistrements
Différentes méthodes permettent de rechercher des enregistrements spécifiques
dans une table. Le moyen le plus souple consiste à utiliser les méthodes
génériques Locate et Lookup. Ces méthodes vous permettent de lancer une
recherche sur n’importe quel type de colonne dans n’importe quelle table, qu’elle
soit ou non indexée.
En ce qui concerne les tables avec des clés multicolonnes, vous ne pouvez
rechercher les valeurs que dans des colonnes contiguës, en commençant par la
première. Par exemple, pour une clé portant sur trois colonnes, vous pouvez
rechercher des valeurs dans la première colonne, puis dans la première et la
seconde, ou bien dans la première, la seconde et la troisième, mais pas seulement
dans la première et la troisième.
Tri d’enregistrements
Un index définit l’ordre d’affichage des enregistrements d’une table. En général,
ils sont affichés par ordre croissant en fonction d’un index primaire (pour les
tables dBASE sans index primaire, l’ordre de tri dépend de l’ordre physique des
enregistrements). Ce comportement par défaut ne nécessite aucune intervention
de l’application. En revanche, si vous voulez obtenir un ordre de tri différent,
vous devez spécifier :
• Un index alternatif ou secondaire.
• Une liste de colonnes sur lesquelles doit s’opérer le tri (SQL seulement).
Pour spécifier un ordre de tri différent, procédez comme suit :
1 Déterminez les index disponibles.
2 Spécifiez l’index secondaire ou la liste de colonnes à utiliser.
La façon la plus simple d’affecter des valeurs de fin de portée est d’appeler la
méthode FieldByName. Par exemple :
with Table1 do
begin
SetRangeStart;
FieldByName('LastName') := Edit1.Text;
SetRangeEnd;
FieldByName('LastName') := Edit2.Text;
ApplyRange;
end;
Pour un index à plusieurs colonnes, vous pouvez spécifier une valeur de départ
pour tous les champs de l’index ou pour certains de ces champs. Si aucune
valeur n’est fournie pour l’un des champs utilisés dans l’index, une valeur NULL
est affectée au champ lors de l’application de la portée. Si le nombre de valeurs
défini est supérieur au nombre de champs dans l’index, une exception est
provoquée.
Pour mettre fin à la spécification de fin de la portée, appelez ApplyRange. Pour
plus d’informations sur l’application d’une portée, voir “Application d’une
portée” à la page 20-16.
Remarque Il est aussi possible de définir les valeurs de fin (et de début) d’une portée en
appelant la procédure SetRange. Pour plus d’informations sur SetRange, voir la
section suivante.
dialogue demande si vous voulez renommer la table. Vous pouvez alors choisir
de renommer la table ou d’annuler l’opération ce qui modifie la propriété
TableName (par exemple pour créer une nouvelle table) sans modifier le nom de
la table représentée par l’ancienne valeur de TableName.
Pour renommer une table Paradox ou dBASE à l’exécution, appelez la méthode
RenameTable du composant table. Ainsi, l’instruction suivante change le nom de
la table Customer en CustInfo :
Customer.RenameTable(‘CustInfo’);
Par exemple, le code suivant met à jour les enregistrements de la table en cours
à partir des enregistrements de la table Customer :
Table1.BatchMove('CUSTOMER.DB', batUpdate);
BatchMove renvoie le nombre d’enregistrements importés.
Attention L’importation d’enregistrements en utilisant le mode batCopy écrase les
enregistrements existants. Pour préserver ces enregistrements, vous devez plutôt
utiliser batAppend.
Seules quelques fonctions disponibles pour votre application sont directement
effectuées par BatMove par l’intermédiaire du composant TBatchMove. Si vous
devez déplacer une grande quantité de données entre des tables, utilisez le
composant action groupée (TBatchMove) au lieu d’appeler la fonction BatchMove
de la table. Pour plus d’informations sur l’utilisation de TBatchMove, voir la
rubrique suivante, “Utilisation de TBatchMove.”
Utilisation de TBatchMove
TBatchMove encapsule des fonctionnalités du moteur de bases de données
Borland (BDE) qui vous permettent de dupliquer un ensemble de données,
d’ajouter des enregistrements d’un ensemble de données à un autre, de mettre à
jour les enregistrements d’un ensemble de données à partir de ceux d’un autre et
de supprimer dans un ensemble de données les enregistrements existant dans un
autre ensemble de données. TBatchMove est souvent utilisé pour :
• Charger les données d’un serveur dans une source de données locale afin de
les analyser ou d’effectuer d’autres opérations.
• Transférer, dans le cadre d’une opération d’upsizing, une base de données
dans des tables stockées sur un serveur distant.
Le composant action groupée peut créer sur la destination des tables
correspondant aux tables source, en établissant une correspondance automatique
entre les noms de colonne et les types de données.
Si vous créez une table entièrement nouvelle en copiant une table existante, la
table obtenue possède le nom spécifié dans la propriété Name du composant
table vers lequel vous copiez les informations. Le type de table obtenu
présente une structure appropriée au serveur spécifié par la propriété
DatabaseName.
6 Définissez la propriété Mode pour indiquer le type d’opération à réaliser. Les
opérations possibles sont batAppend (opération par défaut), batUpdate,
batAppendUpdate, batCopy et batDelete. Pour plus d’informations sur ces modes,
voir “Spécification d’un mode d’action groupée” à la page 20-23
7 Facultatif : définissez la propriété Transliterate. Lorsqu’elle est à true (valeur
par défaut), les données caractère sont transcrites du jeu de caractères de
l’ensemble de données Source vers le jeu de caractères de l’ensemble de
données Destination, en cas de différence.
8 Facultatif : définissez une association entre les colonnes à l’aide de la propriété
Mappings. Vous n’avez pas à utiliser cette propriété si vous voulez que l’action
groupée associe chaque colonne en fonction de sa position dans les tables source
et destination. Pour plus d’informations sur les correspondances de colonne, voir
“Etablissement d’une correspondance entre les types de données” à la page 20-25.
9 Facultatif : définissez les propriétés ChangedTableName, KeyViolTableName et
ProblemTableName. L’action groupée stocke les enregistrements posant
problème dans la table spécifiée par ProblemTableName. Si vous mettez à jour
une table Paradox par une opération action groupée, les violations de clés
seront signalées dans la table spécifiée par KeyViolTableName.
ChangedTableName liste tous les enregistrements modifiés dans la table
destination lors de l’action groupée. Si vous ne spécifiez pas ces propriétés, les
tables d’erreur ne sont ni créées, ni utilisées. Pour plus d’informations sur la
gestion des erreurs, voir “Gestion des erreurs relatives aux actions groupées”
à la page 20-26.
Ajout
Pour ajouter des données, l’ensemble de données destination doit déjà exister. Si
nécessaire le BDE convertit les données à des tailles et des types de données
appropriés à l’ensemble de données destination. Si la conversion n’est pas
possible, une exception est provoquée et les données ne sont pas ajoutées.
Mise à jour
Pour mettre à jour les données, l’ensemble de données destination doit déjà
exister et avoir un index qui permet d’établir la correspondance entre les
enregistrements. Si les champs de l’index primaire sont utilisés pour établir les
correspondances, les enregistrements pour lesquels des champs indexés dans
l’ensemble de données destination correspondent à des champs indexés dans
l’ensemble de données source sont écrasés avec les données source. Si nécessaire,
le BDE convertit les données à des tailles et des types de données appropriés à
l’ensemble de données destination.
Copie
Pour faire une copie de l’ensemble de données source, l’ensemble de données
destination ne doit pas exister. Si c’est le cas, l’opération action groupée
provoque l’écrasement de l’ensemble de données destination par une copie de
l’ensemble de données source.
Si les ensembles de données source et destination sont gérés par des moteurs de
bases de données de types différents, comme, par exemple Paradox et InterBase,
le BDE crée un ensemble de données destination avec une structure aussi proche
que possible de celle de l’ensemble de données source et effectue
automatiquement les conversions de taille et de type de données en cas de
besoin.
Remarque TBatchMove ne copie pas les structures de métadonnées comme les index, les
contraintes et les procédures stockées. Vous devez recréer ces objets métadonnées
sur votre serveur de bases de données ou utiliser l’explorateur SQL.
Suppression
Pour supprimer des données, l’ensemble de données destination doit déjà exister
et avoir un index qui permet d’établir la correspondance entre les
enregistrements. Si les champs de l’index primaire sont utilisés pour établir les
correspondances, les enregistrements pour lesquels des champs indexés dans
l’ensemble de données destination correspondent à des champs indexés dans
l’ensemble de données source sont supprimés dans la table destination.
• KeyViolTableName, si spécifiée, crée une table Paradox locale contenant tous les
enregistrements de la table source qui ont généré une violation d’intégrité lors
de l’utilisation d’une table Paradox. Si AbortOnKeyViol est à True, cette table
contient au plus un enregistrement, car l’opération sera annulée après ce
premier enregistrement.
• ProblemTableName, si spécifiée, crée une table Paradox locale contenant tous les
enregistrements qui n’ont pas pu être placés dans la table destination en
raison d’erreurs de conversion de type de données (si, par exemple, la table
ne pouvait pas contenir les enregistrements d’une table source dont les
données ont dû être tronquées pour tenir dans la table destination). Si
AbortOnProblem est à True, il y a au plus un enregistrement dans la table, car
l’opération est annulée après ce premier problème.
Remarque Si ProblemTableName n’est pas spécifiée, les données de l’enregistrement sont
tronquées et placées dans la table destination.
Généralement, les requêtes sont utilisées pour sélectionner les données visibles
par l’utilisateur dans l’application. Elles permettent d’effectuer des opérations de
mise à jour, d’insertion et de suppression. Lorsque vous utilisez une requête
pour effectuer de telles opérations, elle ne renvoie pas les enregistrements à
l’écran (ce qui n’est pas le cas avec les tables).
Pour plus d’informations sur l’utilisation de la propriété SQL et l’écriture
d’instructions SQL, voir “Spécification de l’instruction SQL à exécuter” à la
page 21-6. Pour plus d’informations sur l’utilisation de paramètres dans les
instructions SQL, voir “Définition de paramètres” à la page 21-9. Pour plus
d’informations sur l’exécution d’une requête, voir “Exécution d’une requête” à la
page 21-13.
Pour en savoir plus sur la propriété SQL et l’écriture d’instructions SQL, voir
“Spécification de l’instruction SQL à exécuter” à la page 21-6. Pour plus
d’informations sur l’utilisation de paramètres dans les instructions SQL, voir
“Définition de paramètres” à la page 21-9. Pour plus d’informations sur la
préparation d’une requête, voir “Préparation d’une requête” à la page 21-15, et
pour plus d’informations sur son exécution, voir “Exécution d’une requête” à la
page 21-13.
Remarque Si l’instruction SQL contenue dans le fichier est une requête paramétrée,
définissez les valeurs initiales des paramètres et appelez la méthode Prepare
avant d’ouvrir ou d’exécuter la requête. L’appel explicite de Prepare se justifie si
la même instruction SQL est fréquemment utilisée ; sinon elle est
automatiquement appelée par le composant requête.
Définition de paramètres
Une instruction SQL paramétrée contient des paramètres, ou variables,
susceptibles de changer pendant la conception ou l’exécution. Ils peuvent
remplacer des valeurs de données, comme celles utilisées dans les clauses WHERE
pour les comparaisons. En règle générale, les paramètres sont utilisés pour
représenter des valeurs transmises à l’instruction. Par exemple, dans l’instruction
INSERT ci-dessous, les valeurs à insérer sont transmises en tant que paramètres :
INSERT INTO Country (Name, Capital, Population)
VALUES (:Name, :Capital, :Population)
Dans cette instruction SQL, :name, :capital et :population représentent les valeurs
réelles fournies à l’instruction par votre application au moment de l’exécution.
Pour la première exécution d’une requête paramétrée, votre application doit
appeler la méthode Prepare pour lier les valeurs en cours des paramètres dans
l’instruction SQL. Cette liaison permet au BDE et au serveur d’allouer des
ressources à l’instruction et à ses paramètres afin d’accélérer la vitesse
d’exécution de la requête.
with Query1 do begin
Close;
Unprepare;
ParamByName(‘Name’).AsString := ‘Belize’;
ParamByName(‘Capital’).AsString := ‘Belmopan’;
ParamByName(‘Population’).AsInteger := ‘240000’;
Prepare;
Open;
end;
Utilisez la propriété Value pour spécifier une valeur pour le paramètre sélectionné
lors de la conception. Cette procédure n’est pas obligatoire lorsque les valeurs des
paramètres sont fournies en phase d’exécution ; laissez alors la propriété Value vide.
Manipulation Chapter 22
22
des procédures stockées
Ce chapitre décrit comment utiliser les procédures stockées dans vos applications
de base de données. Une procédure stockée est un programme autonome écrit
dans le langage de la procédure et du déclencheur propre au système de base de
données utilisé. Il existe fondamentalement deux types de procédures stockées.
Le premier type extrait des données (comme dans le cas d’une requête SELECT).
Les données extraites peuvent se présenter sous la forme d’un ensemble de
données composé d’une ou plusieurs lignes de données, elles-mêmes composées
d’une ou plusieurs colonnes. Autre possibilité, les données extraites se présentent
sous la forme d’unités d’information. Le second type ne renvoie pas de données
mais réalise une action sur les données stockées dans la base de données
(comme dans le cas d’une instruction DELETE). Certains serveurs de base de
données gèrent les deux types d’opération dans une même procédure.
Les procédures stockées qui renvoient des données le font de différentes façons,
en fonction de leur composition et de l’utilisation du système de base de
données. Certaines, comme InterBase, renvoient toutes les données (ensembles de
données et unités d’information) uniquement avec des paramètres de sortie.
D’autres peuvent renvoyer un curseur vers les données. D’autres encore, comme
Microsoft SQL Server et Sybase, peuvent renvoyer un ensemble de données et
des unités.
Dans les applications Delphi, l’accès aux procédures stockées est fourni par les
composants TStoredProc et TQuery. Le choix du composant à utiliser dépend du
codage de la procédure stockée, de la façon dont les données éventuelles sont
renvoyées et de l’utilisation du système de base de données. Les composants
TStoredProc et TQuery sont tous les deux des descendants de TDataSet et héritent
leurs comportements de TDataSet. Pour plus d’informations sur TDataSet, voir
chapitre 18, “Présentation des ensembles de données”.
Prenez par exemple le cas d’une application devant calculer une valeur unique,
comme l’écart-type entre des valeurs pour un grand nombre d’enregistrements.
Pour effectuer ce calcul dans votre application, toutes les valeurs utilisées
doivent être extraites du serveur, d’où un accroissement du trafic réseau. Votre
application doit ensuite effectuer les calculs. Comme ce qui vous intéresse, c’est
le résultat final, c’est-à-dire une valeur représentant l’écart-type ; il sera beaucoup
plus efficace qu’une procédure stockée lise les données sur le serveur, effectue
les calculs puis transmette la valeur recherchée à votre application.
Pour plus de détails sur le support des procédures stockées, reportez-vous à la
documentation de votre serveur de base de données.
Remarque Si votre application change les informations relatives aux paramètres lors de
l’exécution (comme lorsque des procédures surchargées Oracle sont utilisées),
vous devez la préparer à nouveau.
Pour exécuter une procédure stockée préparée, faites appel à la méthode
ExecProc du composant procédure stockée. Le code suivant prépare et exécute
une procédure stockée :
StoredProc1.Params[0].AsString := Edit1.Text;
StoredProc1.Prepare;
StoredProc1.ExecProc;
Remarque Si vous tentez d’exécuter une procédure stockée avant qu’elle n’ait été préparée,
le composant procédure stockée le fait automatiquement à votre place, puis
annule sa préparation après son exécution. Si vous envisagez d’exécuter
plusieurs fois une procédure stockée, il est plus efficace d’appeler Prepare vous-
même, puis d’appeler UnPrepare une seule fois, lorsque vous n’avez plus besoin
d’exécuter la procédure.
Lorsque vous exécutez une procédure stockée, elle peut renvoyer une partie ou
l’ensemble des éléments suivants :
• Un ensemble de données composé d’un ou de plusieurs enregistrements
pouvant être visualisés dans des contrôles orientés données associés à la
procédure stockée par l’intermédiaire d’un composant source de données.
• Des paramètres de sortie.
• Un paramètre résultat contenant des informations d’état sur l’exécution de la
procédure stockée.
Pour déterminer les éléments susceptibles d’être renvoyés par une procédure
stockée sur votre serveur, voir la documentation du serveur.
L’accès aux paramètres de procédure stockée est fourni par les objets TParam de
la propriété TStoredProc.Params. Si le nom de la procédure stockée est spécifié à
la conception dans la propriété StoredProcName, un objet TParam est
automatiquement créé pour chaque paramètre et ajouté à la propriété Params. Si
le nom de la procédure stockée n’est spécifié qu’à l’exécution, les objets TParam
doivent être créés par programmation à ce moment là. La non spécification de la
procédure stockée et la création manuelle des objets TParam permet l’utilisation
d’un seul composant TStoredProc avec un nombre quelconque de procédures
stockées disponibles.
Remarque Certaines procédures stockées renvoient un ensemble de données en plus des
paramètres de sortie et du paramètre résultat. Les applications peuvent afficher
des enregistrements d’ensemble de données dans des contrôles orientés données,
mais doivent traiter séparément les paramètres résultat et de sortie. Pour plus
d’informations sur l’affichage des enregistrements dans des contrôles orientés
données, voir “Utilisation de procédures stockées qui renvoient des ensembles de
résultats” à la page 22-6.
Important Si vous modifiez les noms et les types de données des paramètres d’entrée
rapportés par le serveur, une exception est déclenchée à l’exécution de la
procédure stockée.
Certains serveurs comme Informix ne rapportent pas les noms de paramètres ou
leur type de données. Dans ce cas, utilisez l’explorateur SQL ou les utilitaires du
constructeur pour consulter le code source de la procédure stockée sur le serveur
afin de déterminer les paramètres d’entrée et leur type de données. Voir l’aide
en ligne de l’explorateur SQL pour de plus amples informations.
Si, au moment de la conception, vous ne disposez pas de la liste de paramètres
d’une procédure stockée sur un serveur distant (parce que vous n’êtes pas
connecté à un serveur, par exemple), vous devez appeler l’éditeur de paramètres
de procédure stockée, puis définir la liste des paramètres requis et leur affecter
un type de données et une valeur. Pour plus d’informations sur l’utilisation de
l’éditeur de paramètres de procédure stockée, voir “Définition des informations
sur les paramètres à la conception” à la page 22-15.
Liaison de paramètres
Lorsque vous préparez et exécutez une procédure stockée, ses paramètres
d’entrée sont automatiquement liés aux paramètres du serveur.
La propriété ParamBindMode permet de déterminer la façon dont les paramètres
de votre composant procédure stockée doivent être liés aux paramètres du
serveur. Par défaut la propriété ParamBindMode vaut pbByName, ce qui signifie
que les paramètres du composant procédure stockée sont mis en correspondance
avec ceux du serveur d’après leur nom. C’est la méthode la plus simple pour lier
des paramètres.
Certains serveurs supportent également la liaison de paramètres d’après leur
valeur ordinale, l’ordre dans lequel les paramètres apparaissent dans la
procédure stockée. Dans ce cas, l’ordre dans lequel les paramètres sont spécifiés
dans l’éditeur de collection de paramètres est important. Le premier paramètre
spécifié est mis en correspondance avec le premier paramètre d’entrée sur le
serveur, le deuxième paramètre est mis en correspondance avec le deuxième
paramètre sur le serveur, et ainsi de suite. Si votre serveur supporte la liaison de
paramètres d’après leur valeur ordinale, vous pouvez attribuer la valeur
pbmByNumber à la propriété ParamBindMode.
Astuce Si vous attribuez la valeur pbByNumber à la propriété ParamBindMode, vous devez
spécifier les bons types de paramètres dans un ordre correct. Il est possible de
visualiser le code source de la procédure stockée d’un serveur dans l’explorateur
SQL afin de déterminer si l’ordre et le type des paramètres sont corrects.
Pour plus d’informations sur la définition des valeurs des paramètres, voir
“Définition des informations sur les paramètres à la conception” à la page 22-15.
Remarque Il n’est pas possible de définir les valeurs des paramètres de sortie et des
paramètres résultat. Les valeurs de ces types de paramètres sont définies par
l’exécution de la procédure stockée.
Tableau 23.1
Composant Rôle
TADOConnection Permet d’établir une connexion avec un stockage de données ADO ;
des composants ensemble de données ou commande ADO peuvent
partager cette connexion pour exécuter des commandes, obtenir des
données ou agir sur les métadonnées.
TADODataSet Le composant de base pour obtenir et transformer ses données ; il
peut obtenir les données d’une ou de plusieurs tables; il peut se
connecter directement à un stockage de données ou via un
composant TADOConnection.
TADOTable Permet d’obtenir et de manipuler un ensemble de données provenant
d’une seule table ; il peut se connecter directement à un stockage de
données ou via un composant TADOConnection.
TADOQuery Permet d’obtenir et de manipuler un ensemble de données produit
par une instruction SQL ; il peut également exécuter des instructions
SQL du langage de définition de données (DDL) SQL comme
CREATE TABLE. Il peut se connecter directement à un stockage de
données ou via un composant TADOConnection.
TADOStoredProc Permet d’exécuter des procédures stockées ; il peut exécuter des
procédures stockées renvoyant des données ou exécutant des
instructions DDL. Il peut se connecter directement à un stockage de
données ou via un composant TADOConnection.
TADOCommand Il permet essentiellement d’exécuter des commandes (des instructions
SQL ne produisant pas d’ensemble de résultats); il s’utilise avec un
composant ensemble de données associé. Il peut également obtenir
un ensemble de données d’une table. Il peut se connecter directement
à un stockage de données ou via un composant TADOConnection.
Spécification de la connexion
Si vous voulez utiliser un composant TADOConnection pour fournir une
connexion partagée à des composants ensemble de données et commande ADO,
il faut tout d’abord établir la connexion. Pour ce faire, vous devez spécifier les
informations de connexion appropriées dans la propriété ConnectionString du
composant connexion. A la conception, appelez l’éditeur de chaîne de connexion
en cliquant, dans l’inspecteur d’objet, sur le bouton points de suspension de la
propriété ConnectionString. Cette boîte de dialogue, fournie par le système ADO,
vous permet de construire de manière interactive la chaîne de connexion en
sélectionnant dans des listes les éléments de connexion (comme le fournisseur ou
le serveur). A l’exécution, affectez une valeur String contenant les informations
de connexion à la propriété ConnectionString. L’affectation de la valeur True à la
propriété Connected du composant connexion active la connexion. Cela constitue
un moyen commode de tester la connexion à la conception.
ADOConnection1.ConnectionString := 'Provider=ProviderName;Remote Server=ServerReference';
La propriété ConnectionString contient plusieurs paramètres de connexion séparés
par des points-virgules. Ces paramètres peuvent spécifier le nom d’un
fournisseur, un nom d’utilisateur et un mot de passe (pour l’identification) et
une référence identifiant un serveur distant. La propriété ConnectionString peut
également contenir le nom d’un fichier contenant les paramètres de la connexion.
Un tel fichier doit avoir le même contenu que la propriété ConnectionString : un
ou plusieurs paramètres ayant chacun leur valeur et séparés par des points-
virgules. Pour une liste des paramètres gérés par ADO pour la propriété
ConnectionString, voir l’aide en ligne de la VCL.
Une fois les informations de connexion spécifiées, il est possible d’associer au
composant connexion des composants ensemble de données et commande. Pour
ce faire, affectez une référence au composant connexion dans la propriété
Connection de chaque composant ensemble de données et commande. A la
conception, sélectionnez le composant connexion souhaité dans la liste déroulante
affichée par la propriété Connection dans l’inspecteur d’objet. A l’exécution,
affectez la référence à la propriété Connection. Par exemple, l’instruction suivante
associe un composant TADODataSet à un composant TADOConnection.
ADODataSet1.Connection := ADOConnection1;
Si vous n’activez pas explicitement la connexion en affectant la valeur True à la
propriété Connected du composant connexion, elle est activée automatiquement
quand le premier composant ensemble de données qui l’utilise est activé ou
lorsque la première commande est exécutée pour un composant commande.
La valeur stOpen indique que le composant connexion est actif. Une connexion a
bien été établie avec un stockage de données ADO, sa propriété Active a la
valeur True, et un ou plusieurs des composants commande ou ensemble de
données associés peuvent être actifs.
La valeur stConnecting indique que le composant connexion est en train d’essayer
d’établir la connexion avec le stockage de données ADO spécifié par la propriété
TADOConnection.ConnectionString. Il est possible, dans cet état, d’appeler la
méthode Cancel pour abandonner la tentative de connexion.
ADOTable1.Open;
Table1.FieldByName('Records').AsInteger :=
ADOTable1.RecordCount;
Table1.Post;
end;
finally
SL.Free;
ADOTable1.Close;
end;
end;
Cette section contient des informations sur les fonctionnalités différentes pour la
version ADO des composants ensemble de données par rapport à leurs équivalents
génériques. Ces informations sont proposées dans les sections suivantes :
• Caractéristiques communes à tous les composants ensemble de données ADO
• Utilisation de TADODataSet
• Utilisation de TADOTable
• Utilisation de TADOQuery
• Utilisation de TADOStoredProc
Pour davantage d’informations sur le parcours dans les lignes d’un composant
ensemble de données, voir “Navigation dans les ensembles de données” à la
page 18-10.
Application des mises à jour groupées dans les tables des bases
Pour appliquer les mises à jour en attente qui n’ont pas déjà été appliquées ou
annulées, appelez la méthode UpdateBatch. Pour les lignes dont le contenu a
changé et qui sont appliquées, les modifications sont placées dans les tables de
base sur lesquelles l’ensemble d’enregistrement est basé. Une ligne du cache
marqué pour la suppression entraîne la suppression de la ligne correspondante
de la table de la base. Une insertion d’enregistrement (l’enregistrement existe
dans le cache mais pas dans la table de la base) est ajoutée à la table de la base.
Pour les lignes modifiées, les colonnes des lignes correspondantes des tables de
la base sont modifiées pour adopter les nouvelles valeurs de colonnes présentes
dans le cache.
Utilisée sans paramètre, la méthode UpdateBatch applique toutes les mises à jour
en attente. Il est possible de transmettre une valeur de type TUpdateBatchOptions
comme paramètre de UpdateBatch. Si une valeur autre que ubAffectAll est
transmise, seul un sous-ensemble des modifications en attente est appliqué. Le
paramètre ubAffectAll a le même effet que l’absence de paramètre et provoque
l’application de toutes les mises à jour en attente. L’exemple suivant n’applique
que la ligne en cours :
ADODataSet1.UpdateBatch(ubAffectCurrent);
Utilisation de TADODataSet
Le composant TADODataSet permet aux applications Delphi d’accéder aux
données d’une ou de plusieurs tables d’une base de données via ADO. Les tables
consultées sont spécifiées en utilisant la propriété CommandText du composant
ensemble de données ADO pour indiquer leur nom ou une instruction SQL.
L’accès à la base de données s’effectue par l’intermédiaire d’une connexion à un
stockage de données établie par le composant ensemble de données ADO grâce à
sa propriété ConnectionString ou grâce à un composant TADOConnection distinct
spécifié par la propriété Connection. Pour davantage d’informations, voir
“Connexion à un stockage de données en utilisant des composants ensemble de
données ADO” à la page 23-14.
L’utilisation des données fournies par un composant TADODataSet dans des
contrôles visuels, le parcours des lignes et la modification par code des données
se font de la même manière que pour les autres composants ensemble de
données ADO. Pour davantage d’informations sur les caractéristiques communes
à tous les composants ensemble de données, voir “Caractéristiques communes à
tous les composants ensemble de données ADO” à la page 23-13.
Utilisation de TADOTable
Le composant TADOTable permet aux applications Delphi d’accéder aux données
d’une seule table d’une base de données via ADO. Cette table est spécifiée par la
propriété TableName du composant table ADO.
L’accès à la base de données s’effectue par l’intermédiaire d’une connexion à un
stockage de données établie par le composant table ADO grâce à sa propriété
ConnectionString ou grâce à un composant TADOConnection distinct spécifié par
la propriété Connection. Pour davantage d’informations, voir “Connexion à un
stockage de données en utilisant des composants ensemble de données ADO” à
la page 23-14.
L’utilisation des données fournies par un composant TADOTable dans des
contrôles visuels, le parcours des lignes et la modification par code des données
se font de la même manière que pour les autres composants ensemble de
données ADO. Pour davantage d’informations sur les caractéristiques communes
Utilisation de TADOQuery
Le composant TADOQuery permet aux applications Delphi d’accéder aux
données d’une ou de plusieurs tables d’une base de données ADO en utilisant le
SQL. Spécifiez l’instruction SQL à utiliser par le composant requête ADO dans la
propriété SQL. TADOQuery peut renvoyer des données en utilisant le langage de
manipulation de données (DML) ou créer et modifier des objets de métadonnées
Utilisation de TADOStoredProc
Le composant TADOStoredProc permet aux applications Delphi d’exécuter des
procédures stockées d’une base de données à laquelle on accède en utilisant un
stockage de données ADO. Pour spécifier la procédure stockée à exécuter,
utilisez la propriété ProcedureName du composant procédure stockée ADO.
L’accès à la base de données s’effectue par l’intermédiaire d’une connexion à un
stockage de données établie par le composant procédure stockée ADO grâce à sa
propriété ConnectionString ou grâce à un composant TADOConnection distinct
spécifié par la propriété Connection. Pour davantage d’informations, voir
“Connexion à un stockage de données en utilisant des composants ensemble de
données ADO” à la page 23-14.
Les ensembles de résultats d’un composant TADOStoredProc s’utilisent dans une
application de la même manière que ceux des composants requête TStoredProc
standard utilisant le BDE. Utilisez le composant procédure stockée ADO pour
spécifier la propriété DataSet d’un composant TDataSource standard. Le
composant TDataSource se comporte ensuite comme un canal transférant les
données entre le composant procédure stockée ADO et les contrôles orientés
données. Pour davantage d’informations, voir “Utilisation des contrôles orientés
données” à la page 23-14.
Exécution de commandes
Les composants ADO proposés par Delphi permettent à une application
d’exécuter des commandes. Cette section décrit comment exécuter des
commandes et les composants à utiliser pour ce faire.
Dans l’environnement ADO, les commandes sont une représentation sous forme
de texte de demandes d’actions spécifiques à un fournisseur. Ce sont
Spécification de la commande
Pour spécifier la commande exécutée par le composant commande ADO, utilisez
sa propriété CommandText. A la conception, utilisez l’inspecteur d’objet pour
entrer la commande (une instruction SQL, un nom de table ou de procédure)
dans la propriété CommandText. A l’exécution, affectez à la propriété
CommandText une valeur String contenant la commande.
Si vous le souhaitez, spécifiez explicitement le type de commande utilisé à l’aide
de la propriété CommandType. Le type CommandType propose les constantes
suivantes : cmdText (si la commande est une instruction SQL), cmdTable (si c’est
un nom de table) et cmdStoredProc (si la commande spécifie le nom d’une
procédure stockée). A la conception, sélectionnez la valeur appropriée dans la
liste proposée par l’inspecteur d’objet. A l’exécution, affectez une valeur de type
TCommandType à la propriété CommandType.
with ADOCommand1 do begin
CommandText := 'AddEmployee';
CommandType := cmdStoredProc;
...
end;
Annulation de commandes
Après avoir commencé une tentative d’exécution d’une commande (avec la
méthode Execute d’un composant TADOCommand), il est possible d’abandonner
en appelant la méthode Cancel.
procedure TDataForm.ExecuteButtonClick(Sender: TObject);
begin
ADOCommand1.Execute;
end;
procedure TDataForm.CancelButtonClick(Sender: TObject);
begin
ADOCommand1.Cancel;
end;
La méthode Cancel n’a d’effet que si une commande en attente a été exécutée de
manière asynchrone (eoAsynchExecute dans le paramètre ExecuteOptions de la
méthode Execute). Une commande est dite en attente si la méthode Execute a été
appelée mais n’est pas encore achevée ou n’a pas dépassé le délai limite. Il y a
un dépassement de délai si une commande n’est pas terminée ou abandonnée
avant le nombre de secondes spécifié par la propriété CommandTimeout. Pour
définir un délai différent de la valeur par défaut (30 secondes), affectez la valeur
souhaitée à la propriété CommandTimeout avant d’appeler la méthode Execute.
Ces mécanismes peuvent être combinés dans une même application qui utilise le
modèle “briefcase”. Les utilisateurs prennent un cliché des données en les
enregistrant dans un fichier linéaire afin de pouvoir les manipuler “off-line”.
Ultérieurement, l’application client applique les modifications depuis la copie
locale des données vers le serveur d’applications. Ce dernier applique ensuite les
modifications dans la base de données réelle et renvoie les erreurs à l’ensemble
de données client afin qu’elles soient traitées. Pour plus d’informations sur la
construction d’une application avec le modèle “briefcase”, voir “Utilisation du
modèle “briefcase”” à la page 13-20.
Tri et indexation
L’utilisation d’index présente plusieurs avantages pour vos applications :
• Ils permettent aux ensembles de données client de localiser les données
rapidement.
• Ils permettent à votre application de définir des relations entre les ensembles
de données clients, telles que des tables de référence ou des fiches maître/
détail.
• Ils spécifient l’ordre dans lequel les enregistrements apparaissent.
Si un ensemble de données client est utilisé dans une application multiniveau, il
hérite d’un index par défaut et d’un ordre de tri basés sur les données qu’il
reçoit du serveur d’applications. L’index par défaut s’appelle DEFAULT_ORDER.
Il est possible d’utiliser ce classement, mais il est impossible de modifier ou de
supprimer l’index.
En plus de l’index par défaut, l’ensemble de données client gère un deuxième
index, appelé CHANGEINDEX, à partir des enregistrements stockés dans le
journal de modifications (propriété Delta). CHANGEINDEX classe tous les
enregistrements de l’ensemble de données tels qu’ils apparaîtraient si les
modifications de Delta étaient appliquées. CHANGEINDEX est basé sur l’ordre
qu’il a hérité de DEFAULT_ORDER. Comme pour DEFAULT_ORDER, il est
impossible de modifier ou de supprimer l’index CHANGEINDEX.
Vous pouvez utiliser d’autres index existants d’un ensemble de données ou créer
vos propres index. Les sections suivantes décrivent comment créer et utiliser des
index avec des ensembles de données client.
• Les champs qui composent l’index. L’index utilise ces champs pour trier les
enregistrements et localiser les enregistrements dont les champs indexés
présentent une valeur particulière.
• La façon dont l’index trie les enregistrements. Par défaut, les index imposent
un ordre de tri croissant (selon la configuration de la machine). Cet ordre de
tri par défaut tient compte de la casse. Vous pouvez spécifier des options
pour que la totalité de l’index fasse la différence entre les majuscules et les
minuscules ou pour trier par ordre décroissant. Vous pouvez aussi spécifier
une liste de champs à trier sans tenir compte de la casse et une autre liste de
champs à trier par ordre décroissant.
• Le niveau par défaut de regroupement pris en charge par l’index.
Astuce L’indexation et le tri peuvent s’effectuer sur des champs calculés dans des
ensembles de données client.
Les index créés sont triés par ordre alphabétique selon la configuration de votre
machine. Le paramètre ixDescending peut être ajouté dans la liste des options
d’index pour outrepasser la configuration par défaut.
Remarque Lorsque vous créez les index en même temps que l’ensemble de données client,
vous pouvez faire en sorte qu’ils trient certains champs par ordre croissant et
certains autres par ordre décroissant. Voir “Création d’un ensemble de données à
l’aide de définitions de champ et d’index” à la page 13-17 pour plus de détails.
Par défaut, le tri des champs chaîne tient compte de la différence majuscules/
minuscules. Le paramètre ixCaseInsensitive peut être ajouté dans la liste des
options d’index pour outrepasser ce comportement par défaut.
Remarque Lorsque vous créez les index en même temps que l’ensemble de données client,
vous pouvez faire en sorte que certains ne tiennent pas compte de la casse sur
certains champs et que d’autres en tiennent compte sur d’autres champs. Voir
“Création d’un ensemble de données à l’aide de définitions de champ et
d’index” à la page 13-17 pour plus de détails.
Attention Les index que vous ajoutez à l’aide de AddIndex ne sont pas enregistrés lorsque
vous enregistrez l’ensemble de données client dans un fichier.
Indexation à la volée
Au lieu de créer un index faisant partie de l’ensemble de données client, vous
pouvez créer à la volée un index temporaire en spécifiant les champs à utiliser
dans la propriété IndexFieldNames. Les noms de champs à utiliser doivent être
séparés par des points virgules. La position des champs dans la liste est
déterminante.
Remarque Quand l’indexation est effectuée à la volée, il n’est pas possible de spécifier un
index en ordre décroissant ou ne tenant pas compte des différences majuscule/
minuscule.
Attention Les index créés à la volée ne supportent pas le regroupement.
Bien que vous puissiez utiliser ce procédé dans les ensembles de données client,
ces derniers, en enregistrant les valeurs calculées dans leurs données, vous
permettent de réduire au minimum le nombre de fois où les champs calculés
doivent être recalculés. Lorsque les valeurs calculées sont enregistrées avec
l’ensemble de données client, elles doivent toujours être recalculées lorsque
l’utilisateur modifie l’enregistrement en cours mais votre application n’a pas
besoin de recalculer les valeurs chaque fois que l’enregistrement en cours change.
Pour enregistrer les valeurs calculées dans les données de l’ensemble de données
client, utilisez des champs calculés de façon interne à la place de champs calculés.
Les champs calculés de façon interne, comme les champs calculés, sont calculés
dans un gestionnaire d’événement OnCalcFields. Toutefois, vous pouvez optimiser
votre gestionnaire d’événement en vérifiant la propriété State de votre ensemble
de données client. Lorsque State vaut dsInternalCalc, vous devez recalculer les
champs calculés de façon interne. Lorsque State vaut dsCalcFields, il suffit de
recalculer les champs calculés ordinaires.
Pour utiliser des champs calculés de façon interne, vous devez définir les
champs devant être calculés de façon interne avant de créer l’ensemble de
données client. Si vous créez l’ensemble de données client à l’aide de champs
persistants, définissez les champs devant être calculés de façon interne en
sélectionnant InternalCalc dans l’éditeur de champs. Si vous créez l’ensemble de
données client à l’aide de définitions de champ, mettez la propriété
InternalCalcField de la définition de champ adéquate à True.
Remarque D’autres types d’ensembles de données utilisent des champs calculés de façon
interne. Toutefois, les valeurs de ces champs n’y sont pas calculées dans un
gestionnaire d’événement OnCalcFields mais automatiquement par le BDE ou le
serveur de bases de données distant.
Spécification d’agrégats
Pour spécifier que vous voulez opérer des calculs synthétiques à partir des
enregistrements d’un ensemble de données client, utilisez la propriété Aggregates.
Aggregates est un ensemble de spécifications d’agrégat (TAggregate). Vous pouvez
ajouter des spécifications d’agrégat à votre ensemble de données client à l’aide
de l’éditeur de collection lors de la conception ou de la méthode Add de
Aggregates à l’exécution. Si vous souhaitez créer des composants champ pour les
agrégats, créez des champs persistants pour les valeurs synthétisées dans
l’éditeur de champs.
Remarque Lorsque vous créez des champs synthétisés, les objets agrégat appropriés sont
automatiquement ajoutés à la propriété Aggregates de l’ensemble de données
client. Ne les ajoutez-pas de façon explicite lors de la création des champs
persistants synthétisés. Pour plus de détails sur la création des champs
persistants synthétisés, voir “Définition d’un champ agrégat” à la page 19-13.
Pour chaque agrégat, la propriété Expression indique le calcul synthétique qu’elle
représente. Expression peut contenir une simple expression synthétique telle que
Sum(Field1)
ou une expression complexe qui combine les informations de plusieurs champs,
telle que
Sum(Qty * Price) - Sum(AmountPaid)
Les expressions d’agrégat incluent un ou plusieurs opérateurs de synthèse du
tableau 24.1
Les opérateurs de synthèse portent sur des valeurs de champ ou sur des
expressions conçues à partir de valeurs de champ à l’aide des mêmes opérateurs
que ceux utilisés pour la création de filtres. Vous ne pouvez pas, toutefois,
imbriquer des opérateurs de synthèse. Vous pouvez créer des expressions avec
des opérateurs à partir de valeurs synthétisées ou de valeurs synthétisées et de
constantes. Toutefois, vous ne pouvez pas combiner des valeurs synthétisées et
des valeurs de champ, car de telles expressions sont ambiguës (rien n’indique
quel enregistrement doit fournir la valeur de champ.) Ces règles sont illustrées
dans les expressions suivantes :
Le code suivant définit un agrégat maintenu qui indique le montant total des
ventes réalisé par chaque représentant :
Agg.Expression := 'Sum(Amount)';
Agg.IndexName := 'SalesCust';
Agg.GroupingLevel := 1;
Agg.AggregateName := 'Total Rep';
Pour ajouter un agrégat qui synthétise chaque client pour un représentant donné,
créez un agrégat maintenu de niveau 2.
Les agrégats maintenus qui synthétisent un groupe d’enregistrements sont
associés à un index spécifique. La propriété Aggregates peut inclure des agrégats
qui utilisent différents index. Toutefois, seuls les agrégats qui synthétisent la
totalité de l’ensemble de données client et ceux qui utilisent l’index en cours sont
valides. La modification de l’index en cours détermine les agrégats qui sont
valides. Pour déterminer les agrégats valides à un moment donné, utilisez la
propriété ActiveAggs.
Tableau 24.2 Propriétés et méthodes des ensembles de données client pour la gestion des extractions
de données (suite)
Propriété ou méthode Utilisation
PacketRecords (propriété) Spécifie le type ou le nombre d’enregistrements à renvoyer dans
chaque paquet de données.
GetNextPacket (méthode) Extrait le paquet de données suivant du serveur d’applications.
FetchBlobs (méthode) Extrait tous les champs BLOB de l’enregistrement en cours
lorsque le serveur d’applications n’inclut pas de données BLOB
automatiquement.
FetchDetails (méthode) Extrait les ensembles de données détail imbriqués de
l’enregistrement en cours lorsque le serveur d’applications ne
les inclut pas automatiquement dans des paquets de données.
La propriété PacketRecords peut aussi être utilisée pour extraire des informations
métadonnées sur une base de données du serveur d’applications. Pour extraire
des informations métadonnées, PacketRecords doit valoir 0.
L’extraction automatique d’enregistrements est contrôlée par la propriété
FetchOnDemand. Lorsque FetchOnDemand vaut True (la valeur par défaut),
l’extraction automatique est activée. Pour éviter que l’extraction automatique des
enregistrements se produise, mettez FetchOnDemand à False. Si FetchOnDemand est
à False, l’application doit appeler explicitement GetNextPacket pour extraire des
enregistrements.
Les applications qui doivent représenter des ensembles de données très
volumineux accessibles en lecture seulement peuvent désactiver FetchOnDemand
afin que les ensembles de données client n’essaient pas de charger plus de
données que la mémoire ne peut en contenir. Entre les extractions, l’ensemble de
données client libère sa mémoire cache à l’aide de la méthode EmptyDataSet.
Cette approche, toutefois, ne fonctionne pas très bien lorsque le client doit
renvoyer les mises à jour au serveur d’applications.
Vous pouvez aussi sauvegarder les données dans un flux à l’aide de la méthode
SaveToStream. SaveToStream accepte un paramètre : un objet flux qui reçoit les
données.
Remarque Si vous sauvegardez un ensemble de données client alors que des modifications
existent encore dans le journal de modifications, ces modifications ne sont pas
fusionnées avec les données. Lorsque vous rechargez les données à l’aide de la
méthode LoadFromFile ou LoadFromStream, le journal de modifications contient
toujours les modifications non fusionnées. Ce point est important pour les
applications qui supportent le modèle “briefcase”, dans lequel les modifications
finissent par être appliquées à un composant fournisseur sur le serveur
d’applications.
Remarque SaveToFile ne conserve aucun index ajouté à l’ensemble de données client.
Alors que les mises à jour en mémoire cache peuvent minimiser la durée des
transactions et réduire considérablement le trafic réseau, elles ne sont pas
appropriées à toutes les applications client de bases de données fonctionnant sur
des serveurs distants. Les trois considérations suivantes doivent être prises en
compte avant de décider d’utiliser les mises à jour en mémoire cache :
• Les données en mémoire cache sont locales à votre application et ne sont
pas sous contrôle transactionnel. Dans un environnement client/serveur à fort
trafic, cela implique les situations suivantes :
• les autres applications peuvent modifier les données réelles sur le serveur
pendant que vos utilisateurs éditent leur version locale des données ;
• les autres applications ne peuvent pas voir les modifications effectuées par
la vôtre tant qu’elles n’ont pas été appliquées.
• Dans une relation maître/détail, il peut être compliqué de gérer l’ordre
d’application des mises à jour en mémoire cache. C’est surtout le cas pour
les relations maître/détail imbriquées dans lesquelles une table détail est la
table maître d’une autre table détail et ainsi de suite.
• L’application des mises à jour en mémoire cache à des ensembles de
données en lecture seule basés sur des requêtes nécessite l’utilisation
d’objets mise à jour.
Les composants d’accès aux données fournissent des méthodes de mise à jour en
mémoire cache et de contrôle des transactions que vous pouvez introduire dans
le code de votre application afin de gérer ces situations ; toutefois, vous devez
veiller à couvrir tous les scénarios que votre application est susceptible de
rencontrer dans votre environnement de travail.
Pour utiliser les mises à jour en mémoire cache, CachedUpdates doit avoir la
valeur True, soit au moment de la conception (via l’inspecteur d’objets), soit à
l’exécution. Lorsque vous mettez CachedUpdates à True, l’événement
OnUpdateRecord de l’ensemble de données est déclenché s’il existe. Pour plus
d’informations sur l’événement OnUpdateRecord, voir “Création d’un gestionnaire
d’événement OnUpdateRecord” à la page 25-26.
Par exemple, le code ci-dessous active les mises à jour en mémoire cache pour
un ensemble de données :
CustomersTable.CachedUpdates := True;
Lorsque vous activez les mises à jour en mémoire cache, une copie de tous les
enregistrements est placée (ou cachée) dans la mémoire locale. C’est cette copie
des données que les utilisateurs voient et éditent. Les modifications, les
insertions et les suppressions sont aussi placées en mémoire cache. Elles
s’accumulent en mémoire jusqu’à ce que la mémoire cache en cours des
modifications soit appliquée à la base de données. Si les enregistrements
modifiés sont appliqués avec succès dans la base de données, l’enregistrement
contenant ces modifications dans la mémoire cache est libéré.
Remarque L’application des mises à jour en mémoire cache ne provoque pas la
désactivation des mises à jour suivantes. Elle ne fait qu’écrire les modifications
en cours et entraîne leur effacement de la mémoire.
Pour désactiver les mises à jour en mémoire cache pour un ensemble de
données, donnez à CachedUpdates la valeur False. Si vous désactivez les mises à
jour en mémoire cache avant d’appliquer les modifications en suspens, ces
dernières sont supprimées sans notification. Votre application peut tester la
propriété UpdatesPending avant de désactiver les mises à jour en mémoire cache.
Par exemple, le code ci-dessous demande confirmation avant de désactiver les
mises à jour en mémoire cache pour un ensemble de données :
if (CustomersTable.UpdatesPending)
if (Application.MessageBox(“Annuler mises à jour en suspens?”,
“Modifications non validées”,
MB_YES + MB_NO) = IDYES) then
CustomersTable.CachedUpdates = False;
Extraction d’enregistrements
Si les mises à jour en mémoire cache sont activées, les ensembles de données
BDE gèrent par défaut l’extraction automatique des données d’une base de
données en fonction des besoins. Les ensembles de données extraient
suffisamment d’enregistrements pour l’affichage. Lors du traitement, de
nouvelles extractions peuvent se produire. Si votre application a des besoins
spécifiques, elle peut extraire tous les enregistrements à la fois en appelant la
méthode FetchAll de l’ensemble de données. FetchAll crée en mémoire une copie
locale de tous les enregistrements de l’ensemble de données. Si un ensemble de
données contient beaucoup d’enregistrements ou des enregistrements comportant
des champs BLOB volumineux, il n’est pas recommandé d’utiliser FetchAll.
Remarque L’appel à CancelUpdates ne désactive pas les mises à jour en mémoire cache. Il ne
fait que désactiver les mises à jour en suspens. Pour désactiver les futures mises
à jour en mémoire cache, mettez la propriété CachedUpdates à False.
de données. La propriété DataSet des objets mise à jour n’est pas disponible lors
de conception dans l’inspecteur d’objets. Vous pouvez uniquement définir cette
propriété à l’exécution.
UpdateSQL1.DataSet := Query1;
Les instructions SQL de mise à jour contenues dans l’objet mise à jour ne sont
pas automatiquement exécutées lorsque la méthode ApplyUpdates de l’ensemble
de données de mise à jour est appelée. Pour mettre à jour les enregistrements,
vous devez fournir un gestionnaire pour l’événement OnUpdateRecord du
composant ensemble de données et appeler la méthode ExecSQL ou Apply de
l’objet mise à jour. Cela appelle l’objet mise à jour pour chaque enregistrement
qui doit être mis à jour.
Dans le gestionnaire d’événement OnUpdateRecord de l’ensemble de données, les
actions minimales que vous devez réaliser sont les suivantes :
• Appeler la méthode SetParams de l’objet mise à jour (si vous appelez
ultérieurement ExecSQL).
• Exécuter l’objet mise à jour pour l’enregistrement en cours avec ExecSQL ou
Apply.
• Attribuer au paramètre UpdateAction du gestionnaire d’événement la valeur
uaApplied.
Vous pouvez, si vous le souhaitez, procéder à la validation de données, à la
modification de données ou à la réalisation d’autres tâches liées à la mise à jour
de chaque enregistrement.
Remarque Vous pouvez aussi associer un objet mise à jour à l’ensemble de données à l’aide
de la propriété UpdateObject du composant ensemble de données et les suivants à
l’aide de leur propriété DataSet. Le premier objet mise à jour est
automatiquement exécuté lors de l’appel de la méthode ApplyUpdates du
composant ensemble de données. Les autres doivent être exécutés manuellement.
Important N’oubliez pas que les instructions SQL générées ne sont qu’un point de départ
pour créer les instructions de mise à jour. Il est parfois nécessaire de les modifier
pour qu’elles s’exécutent correctement. Ainsi, pour travailler avec des données
contenant des valeurs NULL, il peut être nécessaire de modifier la clause
WHERE pour obtenir :
WHERE field IS NULL
au lieu d’utiliser la variable champ générée. Testez chaque instruction générée
avant de la valider.
Pour passer d’un type d’instruction SQL généré à un autre et l’éditer, utilisez les
boutons radio Type d’instruction.
Pour accepter les instructions et les associer aux propriétés SQL du composant
mise à jour, cliquez sur OK.
Utilisez une valeur entière comme index pour référencer une ligne donnée dans
la propriété. Les propriétés DeleteSQL, InsertSQL et ModifySQL sont accessibles
lors de la conception et à l’exécution.
with UpdateSQL1.DeleteSQL do begin
Clear;
Add(‘DELETE FROM Inventory I’);
Add(‘WHERE (I.ItemNo = :OLD_ItemNo)’);
end;
Ci-après, la troisième ligne d’une instruction SQL est modifiée à l’aide d’un
index de valeur 2 pour la propriété ModifySQL.
UpdateSQL1.ModifySQL[2] := ‘WHERE ItemNo = :ItemNo’;
Remarque Cet exemple part du principe que la propriété ModifySQL du composant mise à
jour se présente comme suit :
UPDATE EmpAudit
SET EmpNo = :EmpNo, Salary = :Salary, Changed = :DateChanged
WHERE EmpNo = :OLD_EmpNo
Dans cet exemple, l’appel à SetParams fournit des valeurs aux paramètres EmpNo
et Salary. Le paramètre DateChanged n’est pas défini parce que son nom ne
correspond pas à celui d’un champ de l’ensemble de données ; de ce fait, la ligne
de code suivante définit cette valeur explicitement.
Propriété DataSet
La propriété DataSet spécifie l’ensemble de données qui fournit les données au
composant source de données. Généralement, les ensembles de données sont
sélectionnés lors de la conception à partir de la liste déroulante de l’inspecteur
d’objets. A l’exécution, vous pouvez changer l’ensemble de données d’un
composant source de données en fonction des besoins. Le code suivant fait
permuter l’ensemble de données entre Customers et Orders pour le composant
source de données CustSource :
with CustSource do
begin
if DataSet = 'Customers' then
DataSet := 'Orders'
else
DataSet := 'Customers';
end;
Vous pouvez aussi définir la propriété DataSet avec un ensemble de données se
trouvant sur une autre fiche afin de synchroniser les contrôles de données des
deux fiches. Par exemple :
procedure TForm2.FormCreate (Sender : TObject);
begin
DataSource1.Dataset := Form1.Table1;
end;
Propriété Name
La propriété Name sert à donner un nom à un composant source de données de
façon à le distinguer des autres sources de données dans votre application. Dans
un module de données, le nom attribué au composant source de données
s’affiche sous son icône.
Généralement, le nom affecté au composant source de données doit donner une
indication sur l’ensemble de données auquel il est associé. Supposons un
ensemble de données, appelé Clients, auquel vous rattachez un composant source
de données en affectant “Clients” à la propriété DataSet du composant source de
données. Pour mettre en évidence la connexion entre l’ensemble de données et la
source dans le module de données, il est souhaitable de définir la propriété Name
de la source avec une valeur comme “SourceClients”.
Propriété Enabled
La propriété Enabled détermine si le composant source de données est connecté à
l’ensemble de données qui lui est associé. La source de données est effectivement
connectée quand Enabled est à True.
Vous pouvez temporairement déconnecter une source de données unique de son
ensemble de données en basculant Enabled à False. Si la valeur de la propriété
Enabled vaut False, tous les contrôles orientés données rattachés au composant
source sont vidés et deviennent inactifs jusqu’à ce que Enabled bascule une
nouvelle fois à True. Toutefois, il est recommandé de contrôler l’accès à un
ensemble de données via ses méthodes DisableControls et EnableControls car elles
agissent sur toutes les sources de données rattachées.
Propriété AutoEdit
La propriété AutoEdit de TDataSource indique si les ensembles de données
connectés à la source de données passent automatiquement en mode édition
quand l’utilisateur débute une frappe de touches dans un contrôle orienté
données lié à l’ensemble de données. Si AutoEdit est à True (la valeur par
défaut), l’ensemble de données passe automatiquement en mode édition quand
l’utilisateur commence une frappe de touches dans un contrôle orienté données
lié. Sinon, l’ensemble de données ne passe en mode édition que si l’application
appelle explicitement sa méthode Edit. Pour plus d’informations concernant les
états d’un ensemble de données, voir “Détermination et définition des états d’un
ensemble de données” au chapitre 18, “Présentation des ensembles de données”.
Evénement OnDataChange
OnDataChange est appelé quand le curseur se déplace sur un nouvel
enregistrement. Quand l’application appelle Next, Previous, Insert ou toute autre
méthode qui provoque le changement de position du curseur, un événement
OnDataChange est déclenché.
Cet événement est utile si une application synchronise manuellement des
composants.
Evénement OnUpdateData
OnUpdateData est appelé quand les données dans l’enregistrement en cours sont
sur le point d’être mises à jour. Par exemple, un événement OnUpdateData se
produit après un appel à Post , mais aussi avant que les données ne soient
effectivement émises dans la base de données.
Cet événement est utile si une application utilise un contrôle standard (non
orienté données) et qu’elle doit assurer sa synchronisation avec un ensemble de
données.
Evénement OnStateChange
OnStateChange est appelé quand l’état d’un ensemble de données associé à la
source de données change. La propriété State d’un ensemble de données sert à
mémoriser son état actuel. OnStateChange peut servir pour accomplir des actions
au fur et à mesure qu’évolue l’état d’un composant TDataSource.
Par exemple, l’état d’un ensemble de données change fréquemment dans le cadre
habituel d’une session de base de données. Pour suivre ces changements, vous
pourriez écrire un gestionnaire d’événement OnStateChange qui affiche l’état en
champ code postal depuis une table distincte. Un composant TDBText relié à la
table des codes postaux permettra d’afficher le champ code postal correspondant
à l’adresse entrée par l’utilisateur.
TDBText extrait le texte affiché du champ spécifié dans l’enregistrement en cours
d’un ensemble de données. De ce fait, le texte affiché est dynamique, c’est-à-dire
qu’il change au fur et à mesure que l’utilisateur navigue dans la table. Pour cette
raison, il ne vous est pas possible de spécifier le texte d’affichage de TDBText au
moment de la conception comme c’est le cas pour les composants TLabel et
TStaticText
Remarque Lorsque vous placez un composant TDBText sur une fiche, vérifiez que sa
propriété AutoSize est à True (la valeur par défaut) ; vous garantissez ainsi que le
contrôle se redimensionne automatiquement pour afficher des données de
largeur variable. Si AutoSize est à False et le contrôle trop étroit, les données
affichées seront tronquées.
Donnez à la propriété ValueChecked une valeur que le contrôle doit écrire dans la
base de données s’il est activé lorsque l’utilisateur passe à un autre
enregistrement. Par défaut, cette valeur est à “true”, mais vous pouvez la
changer en valeur alphanumérique en fonction de vos besoins. Vous pouvez
également entrer une liste d’éléments délimités par des points-virgules comme
valeur de ValueChecked. Si l’un de ces éléments correspond au contenu de ce
champ dans l’enregistrement en cours, la case est activée. Par exemple, vous
pouvez spécifier une chaîne ValueChecked comme :
DBCheckBox1.ValueChecked := 'True;Yes;On';
Si le champ de l’enregistrement en cours contient des valeurs “true”, “Yes” ou
“On”, c’est que la case est activée. Aucune distinction majuscules/minuscules
n’est effectuée pendant la comparaison du champ avec les chaînes de
ValueChecked. Si un utilisateur active une case à cocher pour laquelle il y a
plusieurs chaînes ValueChecked, la première est la valeur écrite dans la base de
données.
Donnez à la propriété ValueUnchecked une valeur que le contrôle doit écrire dans
la base de données s’il n’est pas activé lorsque l’utilisateur passe à un autre
enregistrement. Par défaut, cette valeur est définie comme “false”, mais vous
pouvez lui donner n’importe quelle valeur alphanumérique en fonction de vos
besoins. Vous pouvez également entrer une liste d’éléments délimités par des
points-virgules. Si l’un des éléments correspond au contenu de ce champ dans
l’enregistrement en cours, la case à cocher n’est pas activée.
Une case à cocher orientée données est désactivée à chaque fois que le champ de
l’enregistrement en cours ne contient pas l’une des valeurs de la liste des
propriétés ValueChecked ou ValueUnchecked.
Si le champ associé à la case à cocher est un champ logique, elle est toujours
activée lorsque le contenu du champ est à True et désactivée s’il est à False.
Dans ce cas, les chaînes entrées dans les propriétés ValueChecked et
ValueUnchecked sont sans effet sur les champs logiques.
Indicateur
d’enregistrement
Les propriétés des colonnes dynamiques sont conservées aussi longtemps que le
composant champ associé existe. Si l’ensemble de données d’une grille consiste
en un ensemble de composants champs dynamiques, les champs sont détruits
dès la fermeture de l’ensemble de données. Lorsque les composants champ sont
détruits, les colonnes qui leur sont associées sont également détruites. Si
l’ensemble de données d’une grille consiste en un ensemble de composants
champs persistants, les composants champs existent même si l’ensemble de
données est fermé, de telle sorte que toutes les colonnes associées à ces champs
gardent leurs propriétés à la fermeture de l’ensemble de données.
Remarque Si la propriété Columns.State d’une grille est mise à csDefault à l’exécution, tous
les objets colonnes de la grille sont supprimés (même les colonnes persistantes)
et les colonnes dynamiques sont reconstruites à partir des champs visibles dans
l’ensemble de données de la grille.
Les colonnes persistantes sont indépendantes des composants champ qui leur
sont associés. De plus, il n’est pas nécessaire d’associer les colonnes persistantes
à des objets champ. Si la propriété FieldName d’une colonne persistante est vide,
ou si le nom du champ ne correspond à aucun champ dans l’ensemble de
données actif dans la grille, la propriété Field de la colonne est NULL et la
colonne est dessinée avec des cellules vides. Vous pouvez utiliser une colonne
vide pour afficher des bitmaps ou des histogrammes représentant les données
d’un enregistrement dans une cellule spécifique, par exemple. Pour ce faire, vous
devez surcharger la méthode de dessin par défaut de la cellule.
Il est possible d’associer une ou plusieurs colonnes persistantes au même champ
d’un ensemble de données. Par exemple, vous pouvez afficher un champ contenant
une référence d’article à droite et à gauche d’une large grille pour faciliter la
recherche d’une référence en évitant à l’utilisateur de faire défiler la grille.
Remarque Etant donné que les colonnes persistantes n’ont pas besoin d’être associées à un
champ d’un ensemble de données, et étant donné que plusieurs colonnes
peuvent référencer le même champ, la valeur de la propriété FieldCount d’une
grille personnalisée peut être inférieure ou égale au nombre de colonnes d’une
grille. Notez également que si la colonne sélectionnée dans la grille personnalisée
n’est pas associée à un champ, la propriété SelectedField de la grille est NULL et
la propriété SelectedIndex est à –1.
Les colonnes persistantes peuvent être configurées pour afficher des cellules de
grille sous forme de liste déroulante dans une boîte à options de valeurs de
référence provenant d’un autre ensemble de données ou d’une liste de choix
statique, ou sous forme d’un bouton à points de suspension (…) dans une
cellule, sur laquelle l’utilisateur peut cliquer pour lancer des visionneurs de
données spéciaux ou des boîtes de dialogue en relation avec la cellule en cours.
Dans cet éditeur, entrez les valeurs devant apparaître dans la liste déroulante
pour la colonne sélectionnée. Si la liste de choix contient des données, la colonne
devient une colonne de liste de choix.
Remarque Pour restaurer le comportement par défaut d’une colonne, supprimez tout le
texte de l’éditeur de liste de chaînes.
Lorsque le champ est réduit, seule la colonne apparaît avec une chaîne non
modifiable des champs enfants, séparés par des virgules. Une colonne peut être
étendue et réduite en cliquant sur la flèche dans la barre de titre du champ et en
définissant la propriété Expanded de la colonne. Lorsque la propriété ObjectView
de l’ensemble de données vaut False, chaque champ enfant apparaît dans une
colonne séparée.
Tableau 26.7 Propriétés relatives à l’affichage des champs ADT et tableau dans un composant TDBGrid
Propriété Objet Fonction
Expandable TColumn Spécifie si la colonne peut être étendue pour afficher les
champs enfants dans des colonnes séparées et modifiables.
Expanded TColumn Spécifie si la colonne est étendue.
MaxTitleRows TDBGrid Spécifie le nombre maximum de lignes de titre pouvant
apparaître dans la grille.
ObjectView TDataSet Spécifie si les champs apparaissent aplanis, ou dans un mode
objet, où chaque champ objet peut être développé et réduit.
ParentColumn TColumn Fait référence à l’objet TColumn auquel appartient la
colonne du champ enfant.
Les figures 26.3 et 26.4 montrent la grille avec un champ ADT et un champ
tableau. La figure 26.3 montre les champs réduits, état dans lequel ils ne peuvent
pas être modifiés. La figure 26.4 montre les champs développés. Les champs sont
développés et réduits en cliquant sur la flèche dans leur barre de titre.
Figure 26.3 Contrôle TDBGrid avec Expanded valant False
Tableau 26.8 Options détaillées des propriétés Options du composant TDBGrid (suite)
Option Effet
dgColLines True : (valeur par défaut) affiche une ligne verticale de séparation
entre les colonnes.
False : n’affiche pas de ligne verticale de séparation entre les
colonnes.
dgRowLines True : (valeur par défaut) affiche une ligne horizontale de
séparation entre les enregistrements.
False : n’affiche pas de ligne horizontale de séparation entre les
enregistrements.
dgTabs True : (valeur par défaut) autorise la tabulation entre les champs
des enregistrements.
False : la tabulation fait sortir du contrôle grille.
dgRowSelect True : la barre de sélection occupe toute la largeur de la grille.
False : (valeur par défaut) la sélection d’un champ d’un
enregistrement ne sélectionne que ce champ.
dgAlwaysShowSelection True : (valeur par défaut) la barre de sélection de la grille est
toujours visible, même si un autre contrôle a la focalisation.
False : la barre de sélection n’apparaît dans la grille que si la grille
a la focalisation.
dgConfirmDelete True : (valeur par défaut) demande la confirmation de la
suppression d’enregistrements (Ctrl+Suppr).
False : supprime les enregistrements sans confirmation.
dgCancelOnExit True : (valeur par défaut) annule une insertion en attente lorsque la
focalisation quitte la grille. Cela permet d’éviter des validations
involontaires d’enregistrements vierges ou partiellement vierges.
False : permet à une insertion en attente d’être validée.
dgMultiSelect True : permet aux utilisateurs de sélectionner des lignes non
contiguës en utilisant les touches Ctrl+Maj ou Maj+flèche.
False : (valeur par défaut) ne permet pas à l’utilisateur de
sélectionner plusieurs lignes.
Pour plus d’informations sur les propriétés et les méthodes des grilles de
contrôle de base de données, voir la référence VCL en ligne.
La figure 26.6 montre le navigateur tel qu’il apparaît par défaut lorsque vous le
placez sur une fiche lors de la conception. Le navigateur se compose d’une série
de boutons permettant à l’utilisateur de naviguer d’un enregistrement à l’autre
dans un ensemble de données, et de modifier, supprimer, insérer et valider des
enregistrements. La propriété VisibleButtons du navigateur vous permet d’afficher
ou de cacher dynamiquement un sous-ensemble de ces boutons.
Figure 26.6 Boutons de TDBNavigatorl
Ins. enreg. Suppr. enreg. actif
Enreg. suiv. Ecriture édition
Présentation
Les composants d’aide à la décision apparaissent sur la page Decision Cube de
la palette des composants :
• Le cube de décision, TDecisionCube, est un lieu de stockage de données
multidimensionnelles.
• La source de décision, TDecisionSource, définit l’état actuel du pivot d’une
grille ou d’un graphe de décision.
• La requête de décision, TDecisionQuery, est une forme spécialisée de TQuery
utilisée pour définir les données d’un cube de décision.
• Le pivot de décision, TDecisionPivot, vous permet d’ouvrir et de fermer les
dimensions, ou champs, d’un cube de décision, en appuyant sur des boutons.
• La grille de décision, TDecisionGrid, affiche des données unidimensionnelles ou
multidimensionnelles sous forme d’un tableau.
• Le graphe de décision, TDecisionGraph, affiche les champs en provenance
d’une grille de décision sous forme d’un graphe dynamique, qui change
lorsque les dimensions des données sont modifiées.
La figure 27.1 montre tous les composants d’aide à la décision placés dans une
fiche au moment de la conception.
Figure 27.1 Composants d’aide à la décision au moment de la conception
Requête de décision
Cube de décision
Souce de décision
Pivot de décision
Grille de décision
Graphe de décision
Pour créer une fiche avec des tableaux et des graphes de données
multidimensionnelles, suivez ces étapes :
1 Créez une fiche.
2 Ajoutez ces composants à la fiche et utilisez l’inspecteur d’objets pour les lier
comme indiqué :
• un ensemble de données, habituellement TDecisionQuery (pour plus de
détails, reportez-vous à “Création d’ensembles de données de décision avec
l’éditeur de requête de décision” à la page 27-6) ou TQuery ;
• un cube de décision, TDecisionCube, lié à l’ensemble de données en
définissant la propriété DataSet du cube de décision par le nom de
l’ensemble de données ;
• une source de décision, TDecisionSource, liée au cube de décision en
définissant la propriété DecisionCube de la source de décision par le nom du
cube de décision.
3 Ajoutez un pivot de décision, TDecisionPivot, et liez-le à la source de décision
dans l’inspecteur d’objets en définissant la propriété DecisionSource du pivot
par le nom de la source de décision. Le pivot de décision est facultatif mais
utile ; il permet au développeur de fiches et à l’utilisateur final de changer les
dimensions affichées dans les grilles ou les graphes de décision en appuyant
sur des boutons.
Dans son orientation par défaut (horizontale), les boutons de gauche du pivot
de décision correspondent aux champs de gauche de la grille de décision (les
lignes) ; les boutons de droite correspondent aux champs du haut de la grille
de décision (les colonnes).
Vous pouvez déterminer l’endroit où apparaissent les boutons du pivot de
décision en définissant sa propriété GroupLayout par xtVertical, xtLeftTop ou
xtHorizontal (la valeur par défaut). Pour plus d’informations sur les propriétés
du pivot de décision, reportez-vous à “Utilisation de pivots de décision” à la
page 27-11.
4 Ajoutez un ou plusieurs graphes et/ou grilles de décision, liés à la source de
décision. Pour plus de détails, reportez-vous à “Création et utilisation de
grilles de décision” à la page 27-12 et “Création et utilisation de graphes de
décision” à la page 27-15.
5 Utilisez l’éditeur de requête de décision ou la propriété SQL de
TDecisionQuery (ou TQuery) pour spécifier les tables, les champs et les calculs
récapitulatifs à afficher dans la grille ou dans le graphe. Le dernier champ de
SQL SELECT peut être un champ récapitulatif. Les autres champs de SELECT
doivent être des champs GROUP BY. Pour en savoir plus, reportez-vous à
“Création d’ensembles de données de décision avec l’éditeur de requête de
décision” à la page 27-6.
6 Définissez la propriété Active de la requête de décision (ou d’un autre
composant ensemble de données) à True.
Propriétés et événements
Voici les propriétés et les événements spéciaux qui contrôlent l’aspect et le
comportement des sources de décision :
• La propriété ControlType de TDecisionSource indique si les boutons du pivot de
décision doivent agir comme des cases à cocher (sélections multiples) ou des
boutons radio (sélections mutuellement exclusives).
• Les propriétés SparseCols et SparseRows de TDecisionSource indiquent si les
colonnes ou les lignes sans valeur doivent être affichées ; si True, les colonnes
ou les lignes vides sont affichées.
• TDecisionSource possède les événements suivants :
• OnLayoutChange se produit lorsque l’utilisateur effectue des pivotements ou
des perforations qui réorganisent les données.
• OnNewDimensions se produit lorsque les données elles-mêmes sont
modifiées, par exemple lorsque les champs récapitulatifs ou les dimensions
sont modifiés.
• OnSummaryChange se produit lorsque la valeur récapitulative en cours est
modifiée.
• OnStateChange se produit quand le cube de décision est activé ou désactivé.
• OnBeforePivot se produit lorsque les modifications sont validées mais pas
encore reflétées par l’interface utilisateur. Les développeurs ont la
possibilité d’effectuer les changements, par exemple de capacité ou de l’état
du pivot, avant que l’utilisateur de l’application ne puisse voir le résultat
de son action.
• OnAfterPivot est déclenché après une modification de l’état du pivot. Les
développeurs peuvent intercepter des informations à ce moment.
Vous pouvez utiliser les graphes de décision à la place, ou en plus, des grilles de
décision (qui elles, présentent les références croisées sous forme de tableaux). Les
grilles ou les graphes de décision qui sont liés à la même source de décision
représentent les mêmes dimensions de données. Pour montrer différentes
données récapitulatives pour les mêmes dimensions, vous pouvez lier plusieurs
graphes de décision à la même source de décision. Pour montrer différentes
dimensions, liez les graphes de décision à différentes sources de décision.
Par exemple, dans la figure 27.4, le premier pivot de décision et le premier
graphe sont liés à la première source de décision alors que le second pivot de
décision et le second graphe sont liés à la seconde source de décision. Chaque
graphe peut donc représenter des dimensions différentes.
Figure 27.4 Graphes de décision liés à différentes sources de décision
Pour plus d’informations sur ce qui apparaît dans un graphe de décision, voir la
section suivante, “Affichage du graphe de décision.”
Pour créer un graphe de décision, voir la section précédente, “Création de
graphes de décision.”
Pour connaître les propriétés des graphes de décision et savoir comment changer
l’aspect et le comportement des graphes de décision, voir “Personnalisation du
graphe de décision” à la page 27-17.
• Cliquer avec le bouton gauche sur un bouton de dimension, après avoir choisi
la commande de forage et sélectionner :
• ouvrir dimension, pour revenir au niveau supérieur de cette dimension ;
• toutes les valeurs, pour basculer entre l’affichage dans les grilles de
décision des récapitulations seulement ou des récapitulations plus les autres
valeurs.
• à partir de la liste des catégories disponibles, une catégorie à “forer” pour
connaître les valeurs détail.
• Cliquer avec le bouton gauche sur un bouton de dimension pour ouvrir ou
fermer cette dimension.
• Faire glisser les boutons de dimension depuis la partie lignes vers la partie
colonnes et réciproquement ; ils peuvent ensuite les placer à côté des boutons
existant dans cette partie ou sur l’icône de lignes ou de colonnes.
III
Ecriture d’applications
Part III
distribuées
Les chapitres de cette section présentent les concepts nécessaires à la construction
d’applications distribuées sur un réseau local ou sur internet.
Remarque Les composants décrits dans le chapitre 28 sont disponibles avec l’édition
Entreprise de Delphi. Les composants application serveur Web traités au
chapitre 29 et les composants socket traités au chapitre 30 sont disponibles avec
les éditions Professionnelle et Entreprise.
Ecriture d’applications
Chapter 28
28
CORBA
Delphi fournit des experts et des classes qui facilitent la création d’applications
distribuées basées sur l’architecture Common Object Request Broker Architecture
(CORBA). CORBA est une spécification adoptée par l’Object Management Group
(OMG) pour faire face à la complexité du développement d’applications objet
distribuées.
Comme son nom l’indique, CORBA propose une approche orientée objet de
l’écriture d’applications distribuées. Cette approche est à opposer à l’approche
orientée message telle qu’elle est décrite pour les applications HTTP dans le
chapitre 29, “Création d’applications serveur pour Internet”. Avec CORBA, les
applications serveur mettent en oeuvre des objets qui peuvent être utilisés à
distance par des applications client au travers d’interfaces bien définies.
Remarque COM propose une autre approche orientée objet aux applications distribuées.
Pour plus d’informations sur COM, voir chapitre 44, “Présentation
des technologies COM”. Toutefois, à la différence de COM, CORBA est une
norme qui s’applique à des plates-formes autres que Windows. Cela signifie que
vous pouvez écrire à l’aide de Delphi des clients ou des serveurs CORBA
capables de communiquer avec des applications orientées CORBA s’exécutant sur
d’autres plates-formes.
La spécification CORBA définit la manière dont les applications client
communiquent avec des objets installés sur un serveur. Cette communication est
gérée par un Object Request Broker (ORB). La prise en charge de CORBA par
Delphi se base sur VisiBroker pour C++ ORB (Version 3.3.2) qui offre une
enveloppe spéciale (orbpas.dll) exposant un sous-ensemble de la fonctionnalité
ORB aux applications Delphi.
Sur les clients CORBA, le stub agit comme proxy pour un objet qui peut être
implémenté par le même processus, un autre processus ou une autre machine (un
autre service). Le client interagit avec le stub comme tout autre objet si l’interface
était mise en oeuvre par n’importe quel autre objet. Pour plus d’informations sur
l’utilisation d’interfaces, voir “Utilisation des interfaces” à la page 3-15
Toutefois, à la différence de la plupart des objets qui mettent en œuvre des
interfaces, le stub gère les appels d’interfaces en appelant le logiciel ORB installé
sur la machine client. L’ORB VisiBroker utilise un Smart Agent (osagent) qui
s’exécute quelque part dans le réseau local. Le Smart Agent est un service
d’annuaire distribué dynamique qui localise un serveur disponible fournissant la
mise en oeuvre réelle de l’objet.
Sur le serveur CORBA, le logiciel ORB transmet les appels d’interfaces à un
squelette généré automatiquement. Le squelette communique avec le logiciel ORB
par l’intermédiaire du Basic Object Adaptor (BOA). Il utilise le BOA pour
recenser l’objet auprès du Smart Agent, indique la portée de l’objet (s’il peut être
utilisé sur des machines distantes) et indique quand les objets sont instanciés et
prêts à répondre aux clients.
Stubs et squelettes
Les stubs et les squelettes fournissent le mécanisme qui permet aux applications
CORBA d’effectuer le marshaling des appels d’interfaces. Le Marshaling :
• Accueille un pointeur d’interface dans le processus du serveur et met ce
pointeur à la disposition du code du processus client.
• Transfère les arguments d’un appel d’interface tels qu’ils sont transmis par le
client et les place dans l’espace du processus de l’objet distant.
A chaque appel d’interface, l’appelant place les arguments sur la pile et effectue
un appel de fonction par le biais du pointeur d’interface. Si l’objet ne se trouve
pas dans le même espace de processus que le code qui appelle son interface,
l’appel est transmis à un stub appartenant au même espace de processus. Le stub
écrit les arguments dans un tampon de marshaling et transmet l’appel à l’objet
distant dans une structure. Le squelette serveur dépouille cette structure, empile
les arguments et appelle l’implémentation de l’objet. Fondamentalement, le
squelette recrée l’appel du client dans son propre espace d’adressage.
Pour tout appel d’interface, l’appelant empile les arguments et effectue un appel
de fonction par l’intermédiaire du pointeur d’interface. Si l’objet n’est pas dans le
même espace de processus que le code qui appelle son interface, l’appel est
transmis à un stub qui se trouve dans le même espace de processus.
Les stubs et les squelettes sont créés automatiquement lors de la définition de
l’interface de l’objet. Leurs définitions sont créées dans l’unité _TLB créée lors de
la définition de l’interface. Vous pouvez visualiser cette unité en la sélectionnant
dans la clause uses de votre unité d’implémentation puis en appuyant sur Ctrl-
Entrée. Pour plus d’informations sur la définition de l’interface de l’objet, voir
“Définition d’interfaces d’objets” à la page 28-6.
Lorsqu’un réseau inclut plusieurs Smart Agents, chaque Smart Agent reconnaît
un sous-ensemble des objets disponibles et communique avec les autres Smart
Agents pour localiser les objets qu’il ne peut pas reconnaître directement. En cas
de terminaison imprévue d’un Smart Agent, les objets dont il garde la trace sont
à nouveau automatiquement recensés avec un autre Smart Agent disponible.
Pour plus de détails sur la configuration et l’utilisation des smart agents dans
vos réseaux locaux, voir “Configuration de Smart Agents” à la page 28-19.
Pour des détails sur la manière d’utiliser la liaison dynamique dans vos
applications client CORBA, voir “Utilisation de l’interface d’appel dynamique” à
la page 28-14.
Remarque Le modèle instance par client n’est pas typique de la plupart des
développements CORBA, mais fonctionne plutôt comme le modèle COM, où la
durée de vie d’un objet serveur est gérée par l’usage du client. Ce modèle
permet à Delphi de créer des serveurs qui agissent simultanément comme des
serveurs CORBA et COM.
En plus du modèle d’instanciation, vous devez spécifier le modèle de thread.
Vous pouvez choisir Thread unique ou Multi-thread.
• Si vous choisissez Thread unique, chaque instance d’objet ne recevra qu’une
requête client à la fois. Vous pourrez accéder en toute sécurité aux données
d’instance de votre objet (propriétés ou champs). Toutefois, vous devrez vous
prémunir contre les conflits de threads lors de l’utilisation de variables ou
d’objets globaux.
• Si vous choisissez Multi-thread, chaque connexion client disposera de sa
propre thread dédiée. Toutefois, votre application pourra être appelée
simultanément par plusieurs clients, chacun sur une thread séparée. Vous
devrez vous prémunir contre les accès simultanés aux données d’instance ainsi
qu’à la mémoire globale. L’écriture de serveurs Multi-thread est complexe lors
de l’utilisation d’une instance d’objet partagée, car vous devez vous prémunir
contre les conflits de threads pour toutes les données et tous les objets
contenus dans votre application.
Remarque Vous pouvez enregistrer un fichier .IDL CORBA pour votre interface en cliquant
sur le bouton Exporter dans l’éditeur de bibliothèque de types. Spécifiez que le
fichier .IDL doit utiliser l’IDL CORBA et non l’IDL Microsoft. Utilisez ce fichier
.IDL pour recenser votre interface ou pour générer des stubs et des squelettes
pour d’autres langages.
Les entrées d’un référentiel d’interfaces ne peuvent pas être supprimées tant que
le serveur du référentiel d’interfaces fonctionne. Pour supprimer un élément,
vous devez arrêter le serveur du référentiel d’interfaces, générer un nouveau
fichier .IDL puis démarrer le serveur du référentiel d’interfaces en spécifiant le
fichier .IDL mis à jour.
Une fois l’OAD en fonctionnement, vous pouvez recenser vos interfaces d’objets
en utilisant le programme en ligne de commande oadutil. Vous devez tout
d’abord exporter le fichier .IDL pour vos interfaces. Pour cela, cliquez sur le
bouton Exporter dans l’éditeur de bibliothèque de types et enregistrez la
définition des interfaces en tant que fichier .IDL CORBA.
Ensuite, recensez les interfaces en utilisant le programme oadutil avec la syntaxe
suivante :
oadutil reg [options]
Les arguments disponibles lors du recensement d’interfaces à l’aide d’oadutil
sont les suivants :
Par exemple, la ligne suivante recense une interface d’après son id référentiel :
oadutil reg -r IDL:MyServer/MyObjectFactory:1.0 -o TMyObjectFactory -cpp MyServer.exe -p
unshared
Remarque Vous pouvez obtenir l’ID référentiel de votre interface en examinant le code
ajouté à la section d’initialisation de votre unité d’implémentation. Il s’agit du
troisième argument de l’appel à TCorbaFactory.Create.
Lorsqu’une interface devient indisponible, vous devez annuler son recensement.
Un objet dont le recensement est annulé ne peut plus être activé
automatiquement par l’OAD si un client demande l’objet. Seuls les objets qui ont
été préalablement recensés à l’aide d’oadutil reg peuvent voir leur recensement
annulé.
Pour annuler le recensement d’interfaces, utilisez la syntaxe suivante :
oadutil unreg [options]
Les arguments disponibles pour l’annulation du recensement d’interfaces à l’aide
d’oadutil sont les suivants :
Obtention de l’interface
Pour obtenir une interface pour des appels DII à liaison différée, utilisez la
fonction globale CorbaBind. CorbaBind accepte l’ID référentiel de l’objet serveur ou
un type d’interface. Elle utilise ces informations pour demander une interface à
l’ORB, et utilise cette dernière pour créer un objet stub.
Remarque Pour pouvoir appeler CorbaBind, il faut recenser l’association entre le type d’interface
et son ID référentiel avec le CorbaInterfaceIDManager global.
Si votre application client possède une classe stub recensée pour le type d’interface,
CorbaBind crée un stub de cette classe. Dans ce cas, l’interface renvoyée par CorbaBind
peut être utilisée pour une liaison avancée (par un transtypage avec l’opérateur as)
ou une liaison différée (DII). S’il n’existe pas de classe stub recensée pour le type
d’interface, CorbaBind renvoie l’interface sur un objet stub générique. Un objet stub
générique ne peut être utilisé que pour les appels différés (DII).
Pour utiliser l’interface renvoyée par CorbaBind pour des appels DII, affectez-la à une
variable de type TAny :
var
IntToCall: TAny;
begin
IntToCall := CorbaBind('IDL:MyServer/MyServerObject:1.0');
...
Vous pouvez toujours transmettre directement en paramètres des types simples que
le compilateur convertira en valeurs TAny. Pour les types structurés, vous devez
utiliser les méthodes de conversion de la variable ORB globale pour créer un type
TAny. Le tableau suivant indique la méthode à utiliser pour créer différents types
structurés :
Par exemple, tapez la commande suivante dans une boîte DOS ou choisissez
Exécuter à partir du bouton Démarrer :
osagent -p 11000
Cette commande lance le Smart Agent afin qu’il écoute le port UDP 11000 au
lieu d’écouter le port par défaut (14000). Le changement du port utilisé par le
Smart Agent pour écouter les messages de diffusion vous permet de créer
plusieurs domaines ORB.
Terminologie et standard
La majorité des protocoles contrôlant l’activité Internet sont définis dans des
documents Request for Comment (RFC) gérés par le comité IETF (Internet
Engineering Task Force), comité chargé de l’ingénierie et du développement des
protocoles Internet. Plusieurs documents RFC vous apporteront d’utiles
précisions pour le développement d’applications Internet :
• Le RFC822, “Standard for the format of ARPA Internet text messages,” décrit
la structure et le contenu des en-têtes de messages.
URI et URL
L’URL est un sous-ensemble d’un URI (Uniform Resource Identifier) défini dans
le document RFC1945. Les applications serveur Web génèrent fréquemment un
contenu à partir de plusieurs sources ; le résultat final ne réside pas à un
emplacement précis, mais est créé si nécessaire. Les URI peuvent décrire des
ressources n’ayant pas d’emplacement défini.
Par exemple, pour afficher une page d’images basée sur des critères représentés
par des boutons à l’écran, le client peut générer cet URL :
http://www.TSite.com/art/gallery.dll/animals?animal=dog&color=black
qui décrit un serveur HTTP dans le domaine www.TSite.com. Le client contacte
www.TSite.com, se connecte au serveur HTTP et lui transmet une requête. La
requête est semblable à celle-ci :
GET /art/gallery.dll/animals?animal=dog&color=black HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/3.0b4Gold (WinNT; I)
Host: www.TSite.com:1024
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
ISAPI et NSAPI
Une application serveur Web ISAPI ou NSAPI est une DLL qui est chargée par
le serveur Web. Les informations de requête client sont transmises à la DLL sous
forme de structure et évaluées par les objets TISAPIApplication, qui créent les
objets TISAPIRequest et TISAPIResponse. Chaque message de requête est
automatiquement traité dans un thread distinct.
CGI autonome
Une application serveur Web CGI autonome est une application console qui
reçoit les informations de requête client sur l’entrée standard et transmet les
résultats au serveur sur la sortie standard. Les données sont évaluées par l’objet
TCGIApplication, qui crée le répartiteur, et par les objets TCGIRequest et
TCGIResponse. Chaque message de requête est traité dans une instance distincte
de l’application.
Win-CGI autonome
Une application serveur Web Win-CGI autonome est une application Windows
qui reçoit les informations de requête client depuis un fichier de configuration
(INI) créé par le serveur et écrit les résultats dans un fichier que le serveur
transmet au client. Le fichier INI est évalué par l’objet TCGIApplication, qui crée
le répartiteur, et par les objets TWinCGIRequest et TWinCGIResponse. Chaque
message de requête est traité dans une instance distincte de l’application.
Le module Web
Le module Web (TWebModule) est un descendant de TDataModule ; il s’utilise de
la même façon pour offrir un contrôle centralisé pour les règles de gestion et les
composants non visuels dans l’application Web.
Ajoutez tout générateur de contenu que votre application utilise pour générer les
messages de réponse. Il peut s’agir de générateurs de contenu intégrés, tels que
TPageProducer, TDataSetPageProducer, TDataSetTableProducer, TQueryTableProducer
et TMIDASPageProducer ou de descendants de TCustomContentProducer que vous
avez créés vous-même. Si votre application génère des messages de réponse
incluant des données extraites d’une base de données, vous pouvez ajouter des
composants d’accès aux données ou des composants particuliers pour écrire un
serveur Web qui fait office de client dans une application MIDAS.
Le module Web ne se contente pas de stocker les composants non visuels et des
règles de gestion : il fait aussi office de répartiteur en associant les messages de
requête HTTP reçus aux éléments d’action qui génèrent les réponses à ces
requêtes.
Vous avez peut-être déjà un module de données paramétré avec les composants
non visuels et les règles de gestion que vous souhaitez utiliser dans votre
application Web. Vous pouvez alors remplacer le module Web par ce module de
données : il suffit de supprimer le module Web généré automatiquement et de le
remplacer par votre module de données. Ajoutez ensuite un composant
TWebDispatcher à votre module de données pour qu’il puisse répartir les
messages de requête vers les éléments d’action, comme le ferait un module Web.
Si vous voulez modifier la façon dont les éléments d’action sont choisis pour
répondre aux messages de requête HTTP reçus, dérivez un nouveau composant
répartiteur de TCustomWebDispatcher et ajoutez-le au module de données.
Votre projet ne peut contenir qu’un répartiteur. Il peut s’agir soit du module
Web qui est automatiquement généré lorsque vous créez le projet, soit du
composant TWebDispatcher que vous ajoutez au module de données qui remplace
le module Web. Si un second module de données contenant un répartiteur est
créé lors de l’exécution, l’application serveur Web générera une erreur.
Remarque Le module Web que vous paramétrez en phase de conception est en fait un
modèle. Dans les applications ISAPI et NSAPI, chaque message de requête crée
un thread distinct. Une instance du module Web et de son contenu est créée
dynamiquement pour chaque thread.
Attention Le module Web d’une application serveur Web à base de DLL est mis en
mémoire cache pour une utilisation ultérieure afin d’améliorer les temps de
réponse. L’état du répartiteur et sa liste d’actions ne sont pas réinitialisés entre
deux requêtes. Si vous activez ou désactivez des éléments d’action en cours
d’exécution, vous obtiendrez des résultats imprévisibles lorsque ce module sera
utilisé pour les requêtes client suivantes.
Attention N’incluez pas l’unité forms dans la clause uses du projet après l’unité CGIApp
ou ISAPIApp. Forms déclare en effet une autre variable globale du nom
d’Application et, si elle apparaît après l’unité CGIApp ou ISAPIApp, Application
sera initialisée comme un objet de type erroné.
Le répartiteur Web
Si vous utilisez un module Web, il agit comme un répartiteur Web. Si vous
utilisez un module de données existant, vous devez lui ajouter un composant
(TWebDispatcher). Le répartiteur gère un ensemble d’éléments d’action qui savent
comment répondre à certains types de messages de requête. Lorsque l’application
Web transmet un objet requête et un objet réponse au répartiteur, il choisit un
ou plusieurs éléments d’action pour répondre à la requête.
Eléments d’action
Chaque élément d’action (TWebActionItem) effectue une tâche précise en réponse
à un type spécifique de message de requête.
Les éléments d’action peuvent répondre entièrement à une requête ou n’y
répondre que partiellement et laisser d’autres éléments d’action finir le travail.
Les éléments d’action peuvent envoyer le message de réponse HTTP pour la
requête, ou simplement préparer une partie de la réponse, que d’autres éléments
d’action termineront. Si une réponse est complétée par les éléments d’action mais
non envoyée, l’application serveur Web envoie le message de réponse.
URL de destination
Le répartiteur compare la valeur de la propriété PathInfo d’un élément d’action à
celle de la propriété PathInfo du message de requête. La valeur de cette propriété
doit être le chemin d’accès à l’URL pour toutes les requêtes que l’élément
d’action est prêt à gérer. Par exemple dans cet URL
http://www.TSite.com/art/gallery.dll/mammals?animal=dog&color=black
si la partie /gallery.dll indique l’application serveur Web, le chemin d’accès est
/mammals
Utilisez les informations de chemin d’accès pour indiquer où votre application
Web doit rechercher des informations au moment de traiter des requêtes ou pour
subdiviser votre serveur Web en sous-services logiques.
Envoi de la réponse
Un gestionnaire d’événement OnAction peut renvoyer la réponse au client Web à
l’aide des méthodes de l’objet TWebResponse. Cependant, si aucun élément
d’action n’envoie la réponse au client, elle sera envoyée par l’application serveur
Web si le dernier élément d’action ayant analysé la requête indique que la
requête a été traitée.
La propriété Method peut indiquer toute autre méthode que le client Web
demande au serveur.
Il n’est pas nécessaire que l’application serveur Web fournisse une réponse pour
toutes les valeurs possibles de la propriété Method. Le standard HTTP exige
cependant qu’elle sache répondre aux requêtes GET et HEAD.
La propriété MethodType indique si la valeur de Method est GET (mtGet), HEAD
(mtHead), POST (mtPost), PUT (mtPut) ou une autre chaîne (mtAny). Le
répartiteur fait correspondre la valeur de la propriété MethodType avec celle de la
propriété MethodType de tous les éléments d’action.
Description du contenu
Plusieurs propriétés décrivent le contenu de la réponse. ContentType fournit le
type de support de la réponse, ContentVersion le numéro de version de ce
support. ContentLength indique la longueur de la réponse. Si le contenu est codé
(par compression des données, par exemple), indiquez-le dans la propriété
ContentEncoding. Si le contenu provient d’un autre URI, indiquez-le dans la
propriété DerivedFrom. Si la valeur du contenu tient compte de la date, utilisez
les propriétés LastModified et Expires pour indiquer si le contenu est toujours
valide. La propriété Title peut fournir des informations descriptives sur le
contenu.
Envoi de la réponse
Si vous êtes sûr que le traitement du message de requête est terminé, vous
pouvez envoyer une réponse directement depuis le gestionnaire d’événement
OnAction. L’objet réponse offre deux méthodes d’envoi de réponses :
SendResponse et SendRedirect. Appelez SendResponse pour envoyer une réponse
avec le contenu et les propriétés d’en-tête de l’objet TWebResponse. Si votre action
doit se limiter à orienter le client Web vers un autre URI, utilisez la méthode
SendRedirect, plus efficace.
Si aucun des gestionnaires d’événements n’envoie de réponse, l’application Web
l’envoie lorsque le répartiteur se referme. Cependant, si aucun élément d’action
n’indique qu’il a traité la réponse, l’application ferme la connexion au client Web
sans envoyer de réponse.
Modèles HTML
Un modèle HTML est une suite de commandes HTML et de balises HTML
transparentes. Une balise HTML transparente est au format :
<#Nom_de_balise Param1=Valeur1 Param2=Valeur2 ...>
Les crochets (< et >) définissent la portée de la balise. Le signe “#” vient
immédiatement après le crochet ouvrant, sans espace entre les deux. Il indique
au générateur de page que la chaîne qui suit est une balise HTML transparente.
Le nom de la balise suit immédiatement le signe dièse, sans espace entre les
deux. Le nom de la balise peut être tout identificateur valide ; il identifie le type
de conversion représenté par la balise.
Après un nom de balise, une balise HTML transparente peut parfois comporter
des paramètres fournissant des informations sur la conversion à effectuer.
Chaque paramètre est au format Paramètre=Valeur. Aucun espace ne doit figurer
entre le nom du paramètre, le signe égal et la valeur. Les paramètres sont
séparés par des espaces.
Les crochets (< et >) rendent la balise transparente pour les navigateurs HTML
qui ne reconnaissent pas la syntaxe “#Nom_de_balise”.
Bien que vous puissiez créer vos propres balises HTML transparentes pour
représenter tout type d'informations traitées par votre générateur de page,
C++Builder met à votre disposition plusieurs noms de balises associés à des
valeurs du type de données TTag. Ces noms de balise prédéfinis corrrespondent
aux commandes HTML susceptibles de varier d'un message de réponse à l'autre.
Ils sont décrits dans le tableau suivant :
Nom de la Valeur
balise de TTag La balise est convertie en :
Link tgLink Lien hypertexte. Le résultat est une séquence HTML
commençant par la balise <A> et se terminant par </A>.
Image tgImage Graphique. Le résultat est une balise HTML <IMG>.
Nom de la Valeur
balise de TTag La balise est convertie en :
Table tgTable Tableau HTML. Le résultat est une séquence HTML
commençant par la balise <TABLE> et se terminant par la
balise </TABLE>.
ImageMap tgImageMap Graphique contenant des zones sensibles. Le résultat est une
séquence HTML commençant par la balise <MAP> et se
terminant par </MAP>.
Object tgObject Objet ActiveX incorporé. Le résultat est une séquence HTML
commençant par la balise <OBJECT> et se terminant par la
balise </OBJECT>.
Embed tgEmbed DLL compatible Netscape. Le résultat est une séquence
HTML commençant par la balise <EMBED> et se terminant
par la balise </EMBED>.
Tout autre nom de balise est associé à tgCustom. Le générateur de page n’offre
aucun traitement spécifique des noms de balises prédéfinis. Ils sont simplement
fournis pour aider vos applications à structurer le processus de conversion des
tâches les plus fréquentes.
Remarque Les noms de balises prédéfinis tiennent compte de la différence entre majuscules
et minuscules.
Simulation du serveur
Pour les applications Win-CGI, vous pouvez simuler le serveur en créant le
fichier de configuration contenant les informations de requête. Lancez ensuite
l’application Win-CGI en lui passant l’emplacement du fichier contenant les
informations sur le client et l’emplacement du fichier que le programme Win-
CGI doit utiliser pour créer le contenu. Vous pouvez ensuite déboguer
l’application.
Services et ports
La plupart des services standard sont associés, par convention, à des numéros de
ports précis. Nous étudierons plus tard ces numéros de ports. Pour l’instant,
considérez le numéro de port comme un code numérique pour ce service.
Si vous implémentez un service standard, les objets socket Windows fournissent
des méthodes de recherche de numéro de port pour le service. Si vous offrez un
service nouveau, vous pouvez spécifier son numéro de port dans un fichier
SERVICES sur les systèmes sous Windows 95 ou NT. Consultez la
documentation Microsoft traitant des sockets Windows pour de plus amples
informations sur le contenu du fichier SERVICES.
Connexions client
Les connexions client connectent un socket client sur le système local à un socket
serveur sur un système distant. Les connexions client sont lancées par le socket
client. En premier lieu, le socket client doit décrire le socket serveur auquel il
souhaite se connecter. Le socket client recherche ensuite le socket serveur et,
lorsqu’il l’a trouvé, demande une connexion. Le socket serveur peut ne pas
établir immédiatement la connexion. Les sockets serveur gèrent une file d’attente
des demandes de clients et établissent la connexion lorsqu’ils le peuvent. Lorsque
le socket serveur accepte la connexion du client, il envoie au socket client une
description complète du socket serveur auquel il se connecte et la connexion est
finalisée par le client.
Connexions d’écoute
Les sockets serveur ne localisent pas les clients : ils génèrent des “demi-
connexions” passives qui restent à l’écoute des requêtes des clients. Les sockets
serveur associent une file d’attente à leurs connexions d’écoute ; la file d’attente
enregistre les requêtes de connexion lorsqu’elles lui parviennent. Lorsque le
socket serveur accepte une demande de connexion client, il forme un nouveau
socket pour se connecter au client pour que la connexion d’écoute reste ouverte
afin d’accepter d’autres requêtes de clients.
Connexions serveur
Les connexions serveur sont formées par des sockets serveur lorsque le socket
d’écoute accepte une requête du client. La description du socket serveur ayant
effectué la connexion au client est envoyée au client lorsque le serveur accepte la
connexion. La connexion est établie lorsque le socket client reçoit cette
description et effectue véritablement la connexion.
Une description complète d’une connexion par socket inclut les adresses du socket
à chaque extrémité de la connexion. Vous pouvez décrire l’adresse de chaque
extrémité du socket en fournissant l’hôte ou l’adresse IP et le numéro de port.
Avant de faire une connexion par socket, vous devez décrire complètement les
sockets formant ses extrémités. Certaines informations sont disponibles sur le
système exécutant votre application. Par exemple, il n’est pas nécessaire de
décrire l’adresse IP locale d’un socket client car elle est dans le système
d’exploitation.
Les informations à fournir dépendent du type de socket implémenté. Les sockets
client doivent décrire le serveur auquel ils souhaitent se connecter. Les sockets
serveur d’écoute doivent décrire le port représentant le service qu’ils offrent.
Si le nom de l’hôte vous est inconnu, le socket client doit spécifier le système
serveur par son adresse IP. Ce processus donne des recherches plus rapides car,
lorsque vous spécifiez un nom d’hôte, le socket doit rechercher l’adresse IP
associée à ce nom pour localiser le système serveur.
Formation de la connexion
Lorsque les propriétés de votre composant socket client décrivent le serveur
auquel vous souhaitez vous connecter, vous pouvez former la connexion à
l’exécution en appelant la méthode Open. Si vous souhaitez que votre application
forme automatiquement la connexion à son ouverture, mettez la propriété Active
à True lors de la conception, à l’aide de l’inspecteur d’objets.
Fermeture de la connexion
Lorsque vous avez fini de communiquer avec une application serveur sur la
connexion socket, vous pouvez fermer la connexion en appelant la méthode
Close. La connexion peut également être fermée depuis le serveur. Si c’est le cas,
vous en êtes informé par un événement OnDisconnect.
Désignation du port
Pour que votre socket serveur puisse écouter les requêtes de connexion client,
vous devez spécifier un port d’écoute. Vous pouvez spécifier ce port à l’aide de
la propriété Port. Si votre application serveur offre un service standard associé
par convention à un numéro de port précis, vous pouvez spécifier ce numéro de
port indirectement, à l’aide de la propriété Service. Il est recommandé d’utiliser la
propriété Service car il est possible de faire des fautes de saisie en entrant le
numéro de port. Si vous précisez à la fois les propriétés Port et Service, le socket
serveur utilisera le nom du service.
Evénements d’erreurs
Les sockets client génèrent un événement OnError lorsqu’ils reçoivent un
message d’erreur émis par la connexion. Les sockets serveur génèrent un
événement OnClientError.Vous pouvez écrire un gestionnaire d’événement
OnError ou OnClientError pour répondre à ces messages d’erreur. Le gestionnaire
d’événement reçoit des informations sur :
• l’objet socket Windows ayant reçu la notification d’erreur ;
• ce que le socket tentait de faire lorsque l’erreur s’est produite ;
• le code d’erreur fourni par le message d’erreur.
Vous pouvez répondre à l’erreur dans le gestionnaire d’événement et mettre le
code d’erreur à 0 pour empêcher le socket de déclencher une exception.
Evénements client
Lorsqu’un socket client ouvre une connexion, les événements suivants se
produisent :
1 Un événement OnLookup se produit avant une tentative de localisation du
socket serveur. A ce moment-là, vous ne pouvez pas modifier les propriétés
Host, Address, Port ou Service pour changer le socket serveur qui est localisé.
Vous pouvez utiliser la propriété Socket pour accéder à l’objet socket
Windows client et utiliser sa propriété SocketHandle pour faire des appels
d’API Windows qui affectent les propriétés client du socket. Par exemple, si
vous souhaitez définir le numéro de port sur l’application client, faites-le
avant que le serveur client ne soit contacté.
2 Le socket Windows est paramétré et initialisé pour la notification
d’événements.
3 Un événement OnConnecting se produit après que le serveur socket soit
localisé. A ce moment, l’objet Windows Socket accessible par la propriété
Socket peut fournir des informations sur le serveur socket qui sera à l’autre
extrémité de la connexion. Ceci est la première possibilité d’obtenir le numéro
de port et l’adresse IP utilisés pour la connexion, qui peuvent différer du
numéro de port de l’adresse IP du socket d’écoute qui a accepté la connexion.
4 La demande de connexion est acceptée par le serveur et gérée par le socket
client.
5 Un événement OnConnect se produit après l’établissement de la connexion. Si
votre socket doit immédiatement lancer la lecture ou l’écriture sur la
connexion, créez un gestionnaire d’événement OnConnect.
Evénements serveur
Les composants socket serveur forment deux types de connexions : les
connexions d’écoute et les connexions aux applications client. Le socket serveur
reçoit des événements lors de la formation de ces deux types de connexions.
Evénements d’écoute
Juste avant que la connexion d’écoute soit formée, l’événement OnListen se
produit. Vous pouvez alors obtenir l’objet socket serveur Windows par le biais
de la propriété Socket. Vous pouvez utiliser sa propriété SocketHandle pour
modifier le socket avant qu’il ne soit ouvert pour l’écoute. Par exemple, si vous
souhaitez restreindre les adresses IP que le serveur utilise pour les écoutes, vous
pouvez le faire dans un gestionnaire d’événement OnListen.
Connexions bloquantes
Lorsque la connexion est bloquante, votre socket doit initier la lecture ou
l’écriture sur la connexion, plutôt qu’attendre la notification émanant de la
connexion socket. Utilisez un socket bloquant lorsque votre côté de la connexion
décide du moment où doivent s’effectuer les lectures et les écritures.
Pour les sockets client, mettez la propriété ClientType à ctBlocking pour former
une connexion bloquante. En fonction de ce dont est capable votre application
client, il peut être recommandé de créer un nouveau thread d’exécution pour les
lectures ou les écritures, de telle sorte que votre application puisse continuer
l’exécution du code dans d’autres threads tout en attendant la fin des lectures ou
des écritures sur la connexion.
Pour les sockets serveur, mettez la propriété ServerType à stThreadBlocking pour
former une connexion bloquante. Etant donné que les connexions bloquantes
interrompent l’exécution de tout autre code lorsque le socket attend que des
informations soient écrites ou lues sur la connexion, les composants de socket
serveur génèrent toujours un nouveau thread d’exécution pour chaque connexion
client lorsque le ServerType est à stThreadBlocking.
Utilisation de TWinSocketStream
Quand vous implémentez le thread d’une connexion bloquante, déterminez le
moment où le socket à l’autre extrémité de la connexion est prêt à lire ou écrire.
Les connexions bloquantes n’informent pas le socket du moment où il faut lire ou
écrire. Pour savoir si la connexion est prête, utilisez un objet TWinSocketStream.
TWinSocketStream dispose de méthodes permettant d’aider à coordonner la
chronologie des lectures et écritures. Appelez la méthode WaitForData pour
attendre jusqu’à ce que le socket à l’autre extrémité soit prêt à écrire.
Si vous lisez ou écrivez en utilisant TWinSocketStream, le flux fait un timeout si la
lecture ou l’écriture n’est pas terminée au bout d’un laps de temps spécifié.
Ainsi, l’application socket ne se bloque pas indéfiniment en essayant de lire ou
d’écrire via une connexion perdue.
Remarque Vous ne pouvez pas utiliser TWinSocketStream avec une connexion non
bloquante.
Attention Les sockets serveur placent dans un cache les threads qu’ils utilisent. Assurez-
vous que la méthode ClientExecute effectue les initialisations nécessaires afin qu’il
n’y ait pas de problème quand le thread s’exécute pour la dernière fois.
Pour utiliser votre thread, créez-le dans un gestionnaire d’événements
OnGetThread. Lors de la création du thread, affectez la valeur False au paramètre
CreateSuspended.
IV
Création de composants
Part IV
personnalisés
Les chapitres de cette partie présentent les concepts nécessaires à la conception et
à l’implémentation de composants personnalisés dans Delphi.
Composants et classes
Comme les composants sont des classes, les créateurs de composants manipulent
les objets à un niveau différent de celui des développeurs d’applications. La
création de nouveaux composants nécessite de dériver de nouvelles classes.
Brièvement, il existe deux différences principales entre la création des composants
et leur utilisation dans des applications. Pour la création de composants,
• Vous avez accès à des parties de la classe qui sont inaccessibles aux
programmeurs d’applications.
• Vous ajoutez de nouvelles parties (des propriétés, par exemple) aux composants.
A cause de ces différences, il faut prendre en compte un plus grand nombre de
conventions, et réfléchir à la manière dont les développeurs d’applications vont
utiliser les composants.
Vous pouvez aussi dériver des classes qui ne sont pas des composants et ne
peuvent pas être manipulées dans une fiche. Delphi inclut de nombreuses classes
de ce type, telles que TRegIniFile et TFont.
En les libérant des tâches d’arrière-plan telles que la création des fenêtres, les
composants Delphi permettent aux développeurs de se concentrer sur ce qu’ils
veulent vraiment réaliser. Pour transmettre un handle de fenêtre à une fonction
API, il n’est pas nécessaire de vérifier que le handle existe ni de créer la fenêtre.
Le programmeur est certain que les opérations vont se dérouler correctement et
n’a pas besoin de le contrôler sans cesse.
Bien que la création de composants sans dépendances soit un peu plus longue, le
temps qui y est consacré est généralement très utile. Non seulement cela évite aux
développeurs répétitions et travail fastidieux, mais cela réduit la quantité de
documentation et de support.
Propriétés
Les propriétés donnent au développeur d’applications l’illusion de définir ou de
lire la valeur d’une variable, tout en permettant au concepteur de composants de
dissimuler la structure de données sous-jacente ou de définir un traitement
spécial lorsque la valeur est accédée.
L’utilisation des propriétés présente plusieurs avantages :
• Les propriétés sont disponibles au moment de la conception. Le développeur
d’applications peut définir ou modifier les valeurs initiales des propriétés sans
écrire de code.
• Les propriétés peuvent contrôler les valeurs ou les formats au moment où le
développeur les définit. La validation de la saisie pendant la conception empêche
de commettre des erreurs.
• Le composant peut construire les valeurs appropriées à la demande. L’erreur de
programmation la plus fréquente est de référencer une variable qui n’a été
initialisée. En représentant les données par une propriété, vous êtes sûr qu’une
valeur leur est toujours disponible sur demande.
• Les propriétés vous permettent de cacher les données sous une interface
simple et cohérente. Vous pouvez modifier la façon dont les informations sont
structurées dans une propriété sans que ce changement ne soit perçu par les
développeurs d’applications.
Le chapitre 33, “Création de propriétés”, explique comment ajouter des propriétés
à vos composants.
Evénements
Un événement est une propriété spéciale qui appelle du code, pendant
l’exécution, en réponse à une saisie ou à une autre opération. Les événements
permettent aux développeurs d’associer des blocs de code spécifiques à des
actions spécifiques, telles des manipulations de la souris ou des frappes au
clavier. Le code qui s’exécute lorsqu’un événement survient est appelé le
gestionnaire de l’événement.
Les événements permettent aux développeurs d’applications de spécifier des
réponses différentes en fonction des actions possibles sans avoir à créer de
nouveaux composants.
Le chapitre 34, “Création d’événements”, explique comment implémenter des
événements standard et comment en définir de nouveaux.
Méthodes
Les méthodes de classes sont des fonctions et procédures qui opèrent sur une
classe plutôt que sur des instances particulières de cette classe. Par exemple, les
méthodes constructeur de composants (Create) sont toutes des méthodes de
classes. Les méthodes de composants sont des procédures et fonctions qui
opèrent sur les instances des composants elles-mêmes. Les développeurs
d’applications utilisent des méthodes pour que les composants effectuent des
actions particulières ou renvoient des valeurs non contenues par des propriétés.
Comme elles nécessitent une exécution de code, les méthodes ne sont disponibles
qu’au moment de l’exécution. Elles sont utiles pour plusieurs raisons :
• Les méthodes encapsulent la fonctionnalité d’un composant dans l’objet même
où résident les données.
• Les méthodes peuvent cacher des procédures compliquées sous une interface
simple et cohérente. Un développeur d’applications peut appeler la méthode
AlignControls d’un composant sans savoir comment elle fonctionne ni si elle
diffère de la méthode AlignControls d’un autre composant.
• Les méthodes permettent de mettre à jour plusieurs propriétés avec un seul
appel.
Le chapitre 35, “Création de méthodes”, explique comment ajouter des méthodes
à vos composants.
Si vous avez déjà écrit une application Windows graphique, vous connaissez les
contraintes imposées par l’interface graphique Windows (GDI), comme les limites
sur le nombre de contextes de périphériques disponibles et l’obligation de restaurer
l’état initial des objets graphiques avant de les détruire.
Avec Delphi, vous n’avez pas besoin de vous en préoccuper. Pour dessiner sur
une fiche ou tout autre composant, il suffit d’accéder à la propriété Canvas du
composant. Pour personnaliser un crayon ou un pinceau, il faut définir une couleur
ou un style. Lorsque vous avez terminé, Delphi dispose des ressources. Delphi
conserve les ressources en mémoire cache pour éviter de les recréer, si votre
application utilise fréquemment le même type de ressources.
Vous pouvez toujours accéder à l’interface GDI Windows, mais votre code sera
beaucoup plus simple et s’exécutera plus rapidement si vous utilisez le canevas
intégré aux composants Delphi. Les fonctionnalités graphiques sont décrites en
détail chapitre 36, “Graphiques et composants”.
Recensement
Avant de pouvoir installer vos composants dans l’EDI de Delphi, vous devez les
recenser. Le recensement indique à Delphi où le composant doit apparaître sur la
palette des composants. Vous pouvez aussi personnaliser la manière dont Delphi
stocke les composants dans le fichier fiche. Le recensement est décrit chapitre 38,
“Accessibilité des composants au moment de la conception”.
protected
{ déclarations protégées }
public
{ déclarations publiques }
published
{ déclarations publiées }
end;
procedure Register ;
implementation
procedure Register ;
begin
RegisterComponents('Samples', [TMyControl]);
end;
end.
Dérivation du composant
Chaque composant est une classe dérivée de TComponent, de l’un de ses
descendants plus spécialisés (tels que TControl ou TGraphicControl) ou d’une
classe composant existante. “Comment créer un composant ?” à la page 31-2
indique les classes à dériver pour obtenir les différentes sortes de composants.
La dérivation des classes est expliquée plus en détail dans la section “Définition
de nouvelles classes” à la page 32-2.
Pour dériver un composant, ajoutez une déclaration de type objet à la partie
interface de l’unité qui contiendra le composant.
Une classe composant simple est un composant non visuel descendant
directement de TComponent.
Pour créer une classe composant simple, ajoutez la déclaration de classe suivante
à la partie interface de votre unité composant :
type
TNewComponent = class(TComponent)
end;
Pour l’instant, le nouveau composant ne fait rien de plus que TComponent. C’est
juste un squelette sur lequel vous allez bâtir votre nouveau composant.
Recensement du composant
Le recensement est une opération simple qui indique à Delphi les composants à
ajouter à la bibliothèque des composants et les pages de la palette sur lesquelles
ils doivent apparaître. Pour une présentation plus détaillée du processus de
recensement, voir chapitre 38, “Accessibilité des composants au moment de la
conception”.
Pour recenser un composant,
1 Ajoutez une procédure nommée Register à la partie interface de l’unité du
composant. Register n’a pas de paramètres, la déclaration est donc très simple :
procedure Register;
Si vous ajoutez un composant à une unité qui contient déjà des composants,
elle doit déjà avoir la procédure Register déclarée, afin que vous n’ayiez pas à
changer la déclaration.
2 Ecrivez la procédureRegister dans la partie implémentation de l’unité, en
appelant RegisterComponents pour chaque composant que vous voulez recenser.
RegisterComponents est une procédure qui prend deux paramètres : le nom
d’une page de palette de composants et un ensemble de types de composants.
Si vous ajoutez un composant à un recensement existant, vous pouvez soit
ajouter le nouveau composant à l’ensemble dans l’instruction existante, soit
ajouter une nouvelle instruction qui appelle RegisterComponents.
Modifier les valeurs par défaut d’une classe pour éviter les répétitions
Dans tout programme, les répétitions superflues sont à proscrire. Si vous vous
surprenez à répéter les mêmes lignes de code, vous serez sans doute amené à les
placer à part dans une sous-routine ou fonction, ou encore à construire une
bibliothèque de routines utilisables par un autre programme. Le même
raisonnement s’applique aux composants. Si vous modifiez fréquemment les
mêmes propriétés ou si vous appelez les mêmes méthodes, vous créerez sans
doute un nouveau composant qui effectue ces tâches par défaut.
Par exemple, supposons qu’à chaque création d’une nouvelle application, vous
ajoutez une boîte de dialogue accomplissant une fonction déterminée. Bien qu’il
soit simple de recréer à chaque fois cette boîte de dialogue, c’est superflu. Vous
pouvez concevoir la boîte de dialogue une fois pour toute, définir ses propriétés
puis installer le composant enveloppe associé dans la palette des composants. En
faisant du dialogue un composant réutilisable, non seulement vous éliminez une
tâche répétitive mais renforcez la standardisation et minimisez les erreurs qui
peuvent être occasionnées par chaque nouvelle création de la boîte de dialogue.
Le chapitre 39, “Modification d’un composant existant”, montre un exemple qui
modifie les propriétés par défaut d’un composant.
Remarque Si vous voulez ne modifier que les propriétés publiées d’un composant existant
ou enregistrer des gestionnaires d’événement spécifiques à un composant ou à
un groupe de composants, vous pourrez accomplir ceci plus facilement en créant
un modèle de composant.
Déclarez les membres en private si vous voulez qu’ils ne soient disponibles que
dans la classe où ils ont été définis. Déclarez-les en protected si vous voulez
qu’ils ne soient disponibles que dans cette classe et ses descendants. Souvenez-
vous que si un membre est disponible n’importe où dans un fichier unité, il est
disponible partout dans ce fichier. Ainsi, si vous définissez deux classes dans la
même unité, elles pourront accéder à l’une ou l’autre des méthodes privées. Et si
vous dérivez une classe dans une unité différente de son ancêtre, toutes les
classes de la nouvelle unité pourront accéder aux méthodes protégées de
l’ancêtre.
Méthodes statiques
Toutes les méthodes sont statiques à moins que vous ne les déclariez
spécifiquement autrement. Les méthodes statiques fonctionnent comme des
procédures ou des fonctions normales. Le compilateur détermine l’adresse exacte
de la méthode et la lie au moment de la compilation.
Le premier avantage des méthodes statiques est qu’elles sont réparties très
rapidement. Comme le compilateur peut déterminer l’adresse exacte de la
méthode, il la lie directement. Les méthodes virtuelles et dynamiques, au
contraire, utilisent des moyens indirects pour donner l’adresse de leurs méthodes
lors de l’exécution, ce qui prend davantage de temps.
Une méthode statique ne change pas lorsqu’elle est héritée d’une classe descendante.
Si vous déclarez une classe comprenant une méthode statique, puis dérivez une
nouvelle classe à partir de celle-ci, la classe dérivée partage exactement la même
méthode à la même adresse. Cela signifie que vous ne pouvez pas redéfinir des
méthodes statiques. Une méthode statique réalise toujours la même chose quelle que
soit la classe qui y est appelée. Si vous déclarez une méthode dans une classe dérivée
ayant le même nom qu’une méthode statique dans la classe ancêtre, la nouvelle
méthode remplace simplement celle héritée dans la classe dérivée.
Méthodes virtuelles
Les méthodes virtuelles emploient un mécanisme de répartition plus compliqué
et plus souple que les méthodes statiques. Une méthode virtuelle peut être
redéfinie dans des classes descendantes, mais est toujours appelée dans la classe
ancêtre. L’adresse d’une méthode virtuelle n’est pas déterminée lors de la
compilation ; à la place, l’objet où la méthode est définie donne l’adresse lors de
l’exécution.
Pour qu’une méthode soit virtuelle, ajoutez la directive virtual après la
déclaration de la méthode. La directive virtual crée une entrée dans le tableau de
méthode virtuelle, de l’objet, ou VMT, qui contient les adresses de toutes les
méthodes virtuelles d’un type objet.
Lorsque vous dérivez une nouvelle classe d’une classe existante, la nouvelle
classe a son propre VMT, qui comprend toutes les entrées provenant du VMT de
l’ancêtre plus toutes les méthodes virtuelles supplémentaires déclarées dans la
nouvelle classe.
Méthodes dynamiques
Les méthodes dynamiques sont des méthodes virtuelles avec un mécanisme de
répartition légèrement différent. Comme les méthodes dynamiques n’ont pas
d’entrées dans le tableau de méthode virtuelle de l’objet, elles peuvent réduire la
taille de la mémoire consommée par les objets. Cependant les méthodes de
répartition dynamiques sont quelque peu plus lentes que les méthodes de
répartition virtuelles normales. Si une méthode est fréquemment appelée, ou si
son exécution nécessite un temps court, vous devrez probablement la déclarer
virtuelle plutôt que dynamique.
Les objets doivent stocker les adresses de leurs méthodes dynamiques. Mais
plutôt que de recevoir les entrées dans le tableau de méthode virtuelle, les
méthodes dynamiques sont indiquées séparément. La liste des méthodes
dynamiques contient des entrées uniquement pour les méthodes introduites ou
surchargées par une classe particulière (le tableau de méthode virtuelle, à
l’inverse, comprend toutes les méthodes virtuelles de l’objet, à la fois héritées et
introduites). Les méthodes dynamiques héritées sont réparties en cherchant
chaque liste de méthode dynamique de l’ancêtre, en allant en arrière dans
l’arborescence de l’héritage.
Pour rendre une méthode dynamique, ajoutez la directive dynamic après la
déclaration de méthode.
Classes et pointeurs
Chaque classe (et par conséquent chaque composant) est en fait un pointeur. Le
compilateur déréférence automatiquement les pointeurs de classe à votre place,
aussi n’avez-vous généralement pas besoin de vous poser ces questions. Le statut
des classes en tant que pointeurs devient important lorsque vous passez une
classe comme paramètre. En général, vous transmettrez les classes par valeur
plutôt que par référence. Car les classes sont déjà des pointeurs, c’est-à-dire des
références ; transmettre une classe par référence serait transmettre une référence à
une référence.
33
Création de propriétés
Chapter 33
Types de propriétés
Une propriété peut avoir un type quelconque. Les divers types sont affichés de
manière différente dans l’inspecteur d’objets, ce qui valide l’affectation des
propriétés effectuées au moment de la conception.
Accès direct
L’accès direct est le moyen le plus simple d’accéder aux données d’une propriété.
Autrement dit, les parties read et write de la déclaration d’une propriété
spécifient que l’affectation ou la lecture de la valeur de la propriété s’effectue
directement dans le champ de stockage interne sans appel à une méthode
d’accès. L’accès direct est utile lorsque vous voulez rendre une propriété
accessible dans l’inspecteur d’objets, mais que vous ne voulez pas que le
changement de sa valeur déclenche un processus immédiatement.
En général, vous définirez un accès direct pour la partie read d’une déclaration
de propriété et utiliserez une méthode d’accès pour la partie write. Cela permet
de mettre à jour l’état du composant lorsque la valeur de la propriété change.
La déclaration de type composant suivante montre une propriété qui utilise
l’accès direct pour les parties read et write.
type
TSampleComponent = class(TComponent)
private { le stockage interne est privé}
FMyProperty: Boolean; { déclare la donnée membre pour contenir la valeur }
published { rend la propriété disponible à la conception }
property MyProperty: Boolean read FMyProperty write FMyProperty;
end;
Méthodes d’accès
Vous pouvez spécifier une méthode d’accès plutôt qu’un champ dans les parties
read et write d’une déclaration de propriété. Les méthodes d’accès doivent être
protected, et sont habituellement déclarées comme virtual ; cela autorise les
composants descendants à surcharger l’implémentation de la propriété.
Evitez de rendre publiques les méthodes d’accès. Les conserver protected vous
prémunit contre toute modification accidentelle d’une propriété par un
développeur d’applications qui appellerait ces méthodes.
Voici une classe qui déclare trois propriétés en utilisant le spécificateur d’index,
qui autorise aux trois propriétés d’avoir les mêmes méthodes d’accès en lecture
et en écriture :
type
TSampleCalendar = class(TCustomGrid)
public
property Day: Integer index 3 read GetDateElement write SetDateElement;
property Month: Integer index 2 read GetDateElement write SetDateElement;
property Year: Integer index 1 read GetDateElement write SetDateElement;
private
function GetDateElement(Index: Integer): Integer; { remarquez le paramètre Index }
procedure SetDateElement(Index: Integer; Value: Integer);
ƒ
Comme chaque élément de la date (day, month et year) est un int et comme la
définition de chacun requiert le codage de la date lorsqu’elle est définie, le code
évite la duplication en partageant les méthodes de lecture et d’écriture pour les
trois propriétés. Vous n’avez besoin que d’une seule méthode pour lire un
élément date et une autre pour écrire l’élément date.
Voici la méthode read qui obtient l’élément date :
function TSampleCalendar.GetDateElement(Index: Integer): Integer;
var
AYear, AMonth, ADay: Word;
begin
DecodeDate(FDate, AYear, AMonth, ADay); { décompose la date codée en éléments }
case Index of
1: Result := AYear;
2: Result := AMonth;
3: Result := ADay;
else Result := -1;
end;
end;
Voici la méthode write qui définit l’élément date approprié :
procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);
var
AYear, AMonth, ADay: Word;
begin
if Value > 0 then { tous les éléments doivent être positifs}
begin
DecodeDate(FDate, AYear, AMonth, ADay); { prend les éléments date actuels }
case Index of { définit le nouvel élément selon Index }
1: AYear := Value;
2: AMonth := Value;
3: ADay := Value;
else Exit;
end;
FDate := EncodeDate(AYear, AMonth, ADay); { code la date modifiée}
Refresh; { actualise le calendrier visible }
end;
end;
Méthode read
La méthode read d’une propriété est une fonction qui n’accepte aucun paramètre
(sauf pour ce qui est mentionné ci-après) et renvoie une valeur du même type
que la propriété. Par convention, le nom de la fonction est Get suivi du nom de
la propriété. Par exemple, la méthode read pour une propriété intitulée Count
serait GetCount. La méthode read manipule les données internes afin de générer
une valeur de la propriété respectant le type demandé.
Les seules exceptions à la règle “aucun paramètre” sont les propriétés tableau et
les propriétés qui utilisent un spécificateur d’index (voir “Création de propriétés
tableau” à la page 33-9), pour lesquelles cet index est transmis comme paramètre.
Utilisez des spécificateurs d’index pour créer une méthode read unique partagée
par plusieurs propriétés. Pour plus d’informations sur les spécificateurs d’index,
consultez le guide du langage Pascal Objet.
Si vous ne déclarez aucune méthode read, la propriété fonctionne uniquement en
écriture. Les propriétés fonctionnant en écriture uniquement sont très rares.
Méthode write
La méthode write d’une propriété est une procédure acceptant un seul paramètre
(sauf pour ce qui est mentionné ci-après) du même type que la propriété. Le
paramètre peut être transmis par référence ou par valeur et peut porter le nom de
votre choix. Par convention, le nom de la méthode write est Set suivi du nom de
la propriété. Par exemple, la méthode write d’une propriété intitulée Count serait
SetCount. La valeur transmise en paramètre devient la nouvelle valeur de la
propriété ; la méthode write doit accomplir les manipulations nécessaires pour
placer les données concernées à l’emplacement de stockage interne de la propriété.
Les seules exceptions à la règle “paramètre unique” sont les propriétés tableau et
les propriétés qui utilisent un spécificateur d’index, pour lesquelles cet index est
transmis comme second paramètre. Utilisez des spécificateurs d’index pour créer
une méthode read unique partagée par plusieurs propriétés. Pour plus
d’informations sur les spécificateurs d’index, consultez le guide du langage Pascal
Objet.
Si vous ne déclarez aucune méthode write, la propriété fonctionne uniquement
en lecture. Pour qu’une propriété publiée puisse être utilisée au moment de la
conception, elle doit être accessible en lecture/écriture.
Les méthodes write testent normalement si une nouvelle valeur diffère de la
valeur actuelle avant de modifier la propriété. Par exemple, voici une méthode
write simple d’une propriété de type entier appelée Count stockant sa valeur
courante dans un champ appelé FCount.
procedure TMyComponent.SetCount(Value: Integer);
begin
if Value <> FCount then
begin
FCount := Value;
Update;
end;
end;
Détermination du stockage
Vous pouvez choisir si Delphi stocke ou non chacune des propriétés de vos
composants. Par défaut, sont stockées toutes les propriétés de la partie published
de la déclaration de classe. Vous pouvez choisir de ne pas stocker une propriété
ou de désigner une fonction qui décidera, au moment de l’exécution, du
stockage de la propriété.
Pour contrôler le stockage par Delphi d’une propriété, ajoutez la directive stored
à la déclaration de propriété, suivie par true, false ou le nom d’une méthode
booléenne.
Le code suivant montre un composant avec la déclaration de trois nouvelles
propriétés. La première est toujours stockée, la deuxième ne l’est jamais et la
troisième est stockée selon la valeur d’une méthode booléenne :
type
TSampleComponent = class(TComponent)
protected
function StoreIt: Boolean;
public { non stockée normalement}
property Important: Integer stored True; { toujours stockée}
published { toujours stockée normalement}
property Unimportant: Integer stored False; { jamais stockée}
property Sometimes: Integer stored StoreIt; { dépend de la valeur de la fonction}
end;
34
Création d’événements
Chapter 34
Bien qu’un gestionnaire d’événement ne puisse pas être une fonction, vous
pouvez toujours obtenir les informations à partir du code du développeur de
l’application en utilisant les paramètres var. Lorsque vous effectuerez ceci,
vérifiez que vous affectez une valeur correcte au paramètre avant d’appeler le
gestionnaire afin de ne pas rendre obligatoire la modification de la valeur par le
code de l’utilisateur.
Un exemple de transmission des paramètres var à un gestionnaire d’événement
est fourni par l’événement OnKeyPress, de type TKeyPressEvent. TKeyPressEvent
définit deux paramètres, l’un indiquant l’objet ayant généré l’événement et
l’autre la touche enfoncée :
type
TKeyPressEvent = procedure (Sender: TObject; var Key: Char) of object;
Normalement, le paramètre Key contient le caractère tapé par l’utilisateur.
Toutefois dans certaines circonstances, l’utilisateur de composant peut souhaiter
changer ce caractère. Par exemple, pour forcer tous les caractères en majuscules
dans un éditeur. Dans un cas comme celui-là, l’utilisateur doit définir le
gestionnaire suivant pour gérer les frappes de touches :
procedure TForm1.Edit1KeyPressed(Sender: TObject; var Key: Char);
begin
Key := UpCase(Key);
end;
Vous pouvez également utiliser les paramètres var pour permettre à l’utilisateur
de surcharger la gestion par défaut.
Comme les événements standard de TControl, les événements des contrôles fenêtrés
disposent de méthodes correspondantes.
Supposons que vous écrivez un composant et que vous souhaitez modifier la façon
dont il répond aux clics de souris. Au lieu d’associer un gestionnaire à l’événement
OnClick, comme le ferait le développeur d’applications, surchargez la méthode
protégée Click :
procedure click override { déclaration forward }
ƒ
procedure TMyControl.Click;
begin
inherited Click; { exécute la gestion standard, y compris l’appel au gestionnaire}
... { vos modifications s’insèrent ici}
end;
Déclenchement de l’événement
Vous avez besoin de savoir ce qui a déclenché l’événement. Pour certains
événements, la réponse est évidente. Par exemple, un événement associé à
l’enfoncement du bouton de souris se produit lorsque l’utilisateur clique avec le
bouton gauche de la souris provoquant l’envoi par Windows d’un message
WM_LBUTTONDOWN à l’application. La réception de ce message provoque l’appel
de la méthode MouseDown d’un composant qui à son tour appelle le code que
l’utilisateur a associé à l’événement OnMouseDown.
Néanmoins, certains événements sont liés de façon moins évidente à des
occurrences externes moins spécifiques. Par exemple, une barre de défilement
dispose d’un événement OnChange qui peut être déclenché par plusieurs
occurrences, telles des frappes de touche, des clics de souris, ou des modifications
dans d’autres contrôles. Lorsque vous définissez vos événements, assurez-vous que
les occurrences appellent tous les événements appropriés.
composant d’une façon qui peut nécessiter une réponse de votre part. Les
événements de modification d’état peuvent aussi être le fait de messages issus de
Windows (par exemple, des changements de focalisation ou d’activation).
Cependant, ils peuvent également survenir à la suite d’une modification de
propriété ou de l’exécution d’une autre partie de code. Vous disposez d’un contrôle
total sur le déclenchement des événements que vous avez vous-même définis.
Définissez les événements avec soin de sorte que les développeurs soient
capables de les comprendre et de les utiliser.
Notifications simples
Un événement de type notification ne fait qu’indiquer qu’un événement particulier
s’est produit sans fournir aucune information sur le moment et l’endroit où il s’est
produit. Les notifications utilisent le type TNotifyEvent, qui véhiculent un
paramètre unique correspondant à l’émetteur de l’événement. Les seuls éléments
“connus” du gestionnaire associé à une notification sont donc le type d’événement
et le composant impliqué. Par exemple, les événements clic de souris sont des
notifications. Lorsque vous écrivez un gestionnaire pour un événement de ce type,
vous ne récupérez que deux informations : le fait qu’un clic s’est produit et le
composant impliqué.
Une notification est un processus à sens unique. Il n’existe aucun mécanisme
pour renvoyer une information en retour ou pour inhiber la gestion d’une
notification.
Déclaration de l’événement
Une fois déterminé le type de votre gestionnaire d’événement, vous pouvez déclarer
le pointeur de méthode et la propriété pour l’événement. N’oubliez pas d’attribuer
un nom à l’événement qui soit à la fois significatif et descriptif pour que
l’utilisateur puisse comprendre son rôle. Dans la mesure du possible, choisissez des
noms de propriétés qui ressemblent à ceux de composants déjà définis.
Appel de l’événement
Il est préférable de centraliser tous les appels à un événement. Autrement dit, créez
une méthode virtuelle dans votre composant qui appelle le gestionnaire
d’événement de l’application (s’il a été défini) et qui fournit une gestion par défaut.
Le fait de rassembler tous les appels à un événement en un seul endroit vous
permet d’être sûr qu’un programmeur, qui dérive un nouveau composant à
partir du vôtre, pourra personnaliser la gestion de l’événement en surchargeant
cette méthode sans avoir à parcourir votre code pour repérer les endroits où
l’événement est appelé.
Deux autres considérations sont à prendre en compte concernant l’appel de
l’événement :
• Les gestionnaires vides doivent être valides.
• Les utilisateurs peuvent surcharger la gestion par défaut.
35
Création de méthodes
Chapter 35
Les méthodes des composants sont des procédures et des fonctions intégrées
dans la structure d’une classe. Il n’existe pratiquement aucune restriction sur ce
que peuvent réaliser les méthodes d’un composant, mais Delphi n’en respecte
pas moins un certain nombre de standards qu’il est préférable de suivre. Ce
sont :
• Eviter les interdépendances
• Noms des méthodes
• Protection des méthodes
• Rendre virtuelles des méthodes
• Déclaration des méthodes
En général, les composants ne doivent pas contenir beaucoup de méthodes et
vous devez chercher à minimiser le nombre des méthodes appelées par une
application. Il est préférable d’encapsuler sous la forme de propriétés des
caractéristiques qu’il serait tentant d’implémenter sous forme de méthodes. Les
propriétés fournissent une interface qui s’inscrit parfaitement dans
l’environnement Delphi et sont accessibles au moment de la conception.
Méthodes abstraites
Une méthode est parfois déclarée abstract dans un composant Delphi. Dans la
VCL, les méthodes abstraites se produisent habituellement dans les classes dont
les noms commencent par “custom”, comme dansTCustomGrid. De telles classes
sont elles-mêmes abstraites, au sens où elles ne servent qu’à la dérivation de
classes descendantes.
Bien que vous puissiez créer un objet instance d’une classe contenant un membre
abstrait, ce n’est pas recommandé. L’appel du membre abstrait entraîne une
exception EAbstractError.
La directive abstract est utilisée pour indiquer des parties de classes qui doivent
être surfacées et définies dans des composants descendants ; cela force les
écrivains de composants à redéclarer le membre abstrait dans des classes
descendantes avant que des instances actuelles de la classe puissent être créées.
public
function CalculateArea: Integer; virtual; { déclare la méthode public virtual }
end;
ƒ
implementation
ƒ
procedure TSampleComponent.MakeBigger; { implémente la première méthode}
begin
Height := Height + 5;
Width := Width + 5;
end;
function TSampleComponent.CalculateArea: Integer; { implémente la deuxième méthode}
begin
Result := Width * Height;
end;
Graphiques et composants
Chapter 36
36
Windows fournit une puissante interface GDI (Graphics Device Interface) servant
à dessiner des graphiques indépendamment des périphériques.
Malheureusement, GDI impose au programmeur des contraintes supplémentaires
telles que la gestion des ressources graphiques. Delphi prend en charge toutes
ces tâches GDI ingrates, vous laisse vous concentrer sur le travail productif, vous
épargnant les recherches de handles perdus ou de ressources non restituées.
De même que toute partie de l’API Windows, vous pouvez appeler les fonctions
GDI directement depuis votre application Delphi. Toutefois, vous vous rendrez
vite compte que l’utilisation de l’encapsulation Delphi des fonctions graphiques
est un moyen plus efficace et plus rapide de créer des graphiques.
Les rubriques de cette section comprennent :
• Présentation des graphiques
• Utilisation du canevas
• Travail sur les images
• Bitmaps hors écran
• Réponse aux changements
Utilisation du canevas
La classe canevas encapsule les graphiques Windows à plusieurs niveaux, allant
des fonctions de haut niveau (pour dessiner des lignes, des formes et du texte)
aux accès GDI de bas niveau, en passant par les propriétés de niveau
intermédiaire, pour manipuler les moyens de dessin du canevas.
Le tableau suivant résume les possibilités du canevas.
Pour plus d’informations sur les classes canevas, leurs méthodes et leurs
propriétés, reportez-vous à l’aide en ligne.
Les trois sujets suivants sont nécessaires à la compréhension du travail sur les
images dans Delphi :
• Utilisation d’une image, d’un graphique ou d’un canevas
• Chargement et stockage des graphiques
• Gestion des palettes
Pour répondre aux modifications d’un objet graphique, vous devez associer une
méthode à l’événement OnChange de sa classe.
Le composant forme publie les propriétés représentant le crayon et le pinceau
qu’il utilise pour tracer sa forme. Le constructeur du composant associe une
méthode à l’événement OnChange de chacun, ce qui a pour effet de provoquer le
rafraîchissement de l’image du composant si le crayon ou le pinceau est modifié :
type
TShape = class(TGraphicControl)
public
procedure StyleChanged(Sender: TObject);
end;
ƒ
implementation
ƒ
constructor TShape.Create(AOwner: TComponent);
begin
inherited Create(AOwner); { appelle toujours le constructeur hérité ! }
Width := 65;
Height := 65;
FPen := TPen.Create; { construit le crayon}
FPen.OnChange := StyleChanged; { affecte la méthode à l’événement OnChange }
FBrush := TBrush.Create; { construit le pinceau}
FBrush.OnChange := StyleChanged; { affecte la méthode à l’événement OnChange }
end;
procedure TShape.StyleChanged(Sender: TObject);
begin
Invalidate(); { détruit et redessine le composant }
end;
protected
procedure CMChangeColor(var Message: TMessage); message CM_CHANGECOLOR;
end;
procedure TMyComponent.CMChangeColor(var Message: TMessage);
begin
Color := Message.lParam;
inherited ;
end;
Les liens vers les classes d’objets, les propriétés ou les événements dans le
système d’aide de Delphi peuvent être réalisés à l’aide de Alinks. Alink opère
la liaison vers une classe d’objet en utilisant le nom de classe de l’objet suivi
d’un caractère de soulignement et de la chaîne “object”. Par exemple, pour
réaliser un lien vers l’objet TCustomPanel, utilisez le code suivant :
!AL(TCustomPanel_object,1)
Pour réaliser un lien vers une propriété, une méthode ou un événement, faites
précéder son nom par celui de l’objet qui l’implémente et par un caractère de
soulignement. Par exemple, pour réaliser un lien vers la propriété Text
implémentée par TControl, utilisez le code suivant :
!AL(TControl_Text,1)
Pour voir un exemple de rubriques de navigation secondaires, affichez l’aide
d’un composant quelconque et cliquez sur les liens étiquetés hiérarchie,
propriétés, méthodes ou événements.
3 Chaque propriété, événement ou méthode déclaré à l’intérieur du composant
doit avoir une rubrique.
Une rubrique décrivant une propriété, un événement ou une méthode doit
indiquer la déclaration de l’élément et décrire son rôle. Les développeurs
d’applications accéderont à cette rubrique en sélectionnant l’élément dans
l’inspecteur d’objets et en appuyant sur F1, ou en plaçant le curseur dans
l’éditeur de code sur le nom de l’élément et en appuyant sur F1. Pour avoir
un exemple de rubrique associée à une propriété, sélectionnez un élément
quelconque dans l’inspecteur d’objets et appuyez sur F1.
Les rubriques de propriété, d’événement et de méthode doivent inclure une
note de bas de page K qui indique le nom de la propriété, de l’événement et
de la méthode, son nom et celui du composant. Ainsi, la propriété Text de
TControl présente la note de bas de page K suivante :
Text,TControl;TControl,Text;Text,
Les rubriques de propriété, de méthode ou d’événement doivent également
comporter une note de bas de page $ indiquant le titre de la rubrique, tel que
TControl.Text.
Toutes ces rubriques doivent disposer d’un identificateur de rubrique unique à la
rubrique, entré sous la forme d’une note de bas de page #.
Tableau 38.2 Méthodes pour lire et écrire les valeurs des propriétés
Type de propriété Méthode Get Méthode Set
Virgule flottante GetFloatValue SetFloatValue
Pointeur de méthode (événement) GetMethodValue SetMethodValue
Type ordinal GetOrdValue SetOrdValue
Chaîne GetStrValue SetStrValue
Lorsque vous surchargez une méthode GetValue, appelez l’une des méthodes
“Get”. Lorsque vous surchargez SetValue, appelez l’une des méthodes “Set”.
Les propriétés Color sont plus polyvalentes que la plupart des autres propriétés,
l’utilisateur dispose de plusieurs moyens pour sélectionner une couleur dans
l’inspecteur d’objets : il peut taper une valeur, sélectionner dans une liste ou faire
appel à l’éditeur personnalisé. C’est pourquoi la méthode GetAttributes de
TColorProperty, inclut plusieurs attributs dans la valeur qu’elle renvoie :
function TColorProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paMultiSelect, paDialog, paValueList];
end;
begin
FontDlg := TFontDialog.Create(Application);
try
if FontDlg.Execute then
MyComponent.FFont.Assign(FontDlg.Font);
finally
FontDlg.Free
end;
end;
Remarque Si vous souhaitez qu’un double-clic sur le composant affiche l’éditeur de code
d’un gestionnaire d’événement, utilisez TDefaultEditor comme classe de base pour
votre éditeur de composants au lieu de TComponentEditor. Puis, au lieu de
surcharger la méthode Edit, surchargez la méthode protégée
TDefaultEditor.EditProperty. EditProperty recherche les gestionnaires d’événement
du composant et affiche le premier qu’il trouve. Vous pouvez modifier ce
comportement pour visualiser un événement particulier. Par exemple :
procedure TMyEditor.EditProperty(PropertyEditor: TPropertyEditor;
Continue, FreeEditor: Boolean)
begin
if (PropertyEditor.ClassName = ‘TMethodProperty’) and
(PropertyEditor.GetName = ‘OnSpecialEvent’) then
// DefaultEditor.EditProperty(PropertyEditor, Continue, FreeEditor);
end;
Catégories de propriété
Dans l’IDE Delphi, l’inspecteur d’objet fournit au programmeur la possibilité de
masquer et d’afficher sélectivement des propriétés basées sur les catégories de
propriété. Les propriétés des nouveaux composants personnalisés peuvent aussi
rentrer dans ce procédé en recensant des propriétés par catégories. Faites ceci
alors que le composant est en cours de recensement en appelant une des
fonctions de recensement de propriété RegisterPropertyInCategory ou
RegisterPropertiesInCategory. Utilisez la première fonction pour recenser une
seule propriété et la dernière pour recenser plusieurs propriétés dans un seul
appel de fonction. Ces fonctions sont définies dans l’unité DsgnIntf.
Notez qu’il n’est pas obligatoire de recenser des propriétés ni que toutes les
propriétés d’un composant personnalisé soient recensées lorsque quelques-unes le
sont. Toute propriété non explicitement associée à une catégorie est considérée
simplement comme étant dans la catégorie TMiscellaneousCategory. Ces
propriétés seront affichées ou masquées dans l’inspecteur d’objet selon cette
catégorisation par défaut.
Delphi propose treize catégories de propriété de stockage, sous la forme de
classes de propriété. Recensez une propriété d’un nouveau composant
personnalisé dans l’une de ces catégories ou créez vos propres classes de
catégorie de propriété à partir de ces classes intégrées.
En plus de ces deux fonctions de recensement de propriétés, il existe une
fonction IsPropertyInCategory. Cette fonction est utile pour des tentatives telles
que la création d’utilitaires de localisation, dans laquelle vous devez déterminer
si une propriété est recensée dans une catégorie de propriété donnée.
Surcharge du constructeur
Lorsque vous placez un composant dans une fiche au moment de la conception ou
lorsqu’une application en cours d’exécution construit un composant, le constructeur
du composant définit les valeurs des propriétés. Quand un composant est chargé
depuis un fichier fiche, l’application définit toutes les propriétés qui ont été
modifiées lors de la conception.
Déclaration de la propriété
Généralement, pour déclarer une propriété, vous déclarez un champ privé pour
stocker les données de la propriété puis vous spécifiez les méthodes pour lire et/
ou écrire sa valeur. Souvent, la méthode pour lire la valeur n’est pas nécessaire
car un simple pointage sur la valeur stockée suffit.
S’agissant de notre contrôle forme, vous aurez à déclarer un champ contenant la
forme courante, puis à déclarer une propriété qui lit ce champ et l’écrit via un
appel de méthode.
Ajoutez les déclarations suivantes dans TSampleShape:
type
TSampleShape = class(TGraphicControl)
private
FShape: TSampleShapeType; { donnée membre pour contenir la valeur de la propriété }
procedure SetShape(Value: TSampleShapeType);
published
property Shape: TSampleShapeType read FShape write SetShape;
end;
Il ne vous reste plus qu’à ajouter l’implémentation de SetShape.
Dans notre exemple, le contrôle forme définit sa taille par un carré de 65 pixels
de côté.
Ajoutez le constructeur surchargé dans la déclaration de la classe composant :
type
TSampleShape = class(TGraphicControl)
public { constructeurs toujours publics }
constructor Create(AOwner: TComponent); override { surcharger la directive }
end;
1 Redéclarez les propriétés Height et Width avec leurs nouvelles valeurs par
défaut :
type
TSampleShape = class(TGraphicControl)
ƒ
published
property Height default 65;
property Width default 65;
end;
2 Ecrivez le nouveau constructeur dans la partie implémentation de l’unité :
constructor TSampleShape.Create(AOwner: TComponent);
begin
inherited Create(AOwner); { appelle toujours le constructeur hérité }
Width := 65;
Height := 65;
end;
Les champs de classe des objets ayant un propriétaire sont presque toujours
déclarés private. Si des applications (ou d’autres composants) ont besoin
d’accéder aux objets ayant un propriétaire, vous devez pour cela déclarer des
propriétés publiées ou publiques.
Ajoutez des champs de classe pour le crayon et le pinceau de votre contrôle forme :
type
TSampleShape = class(TGraphicControl)
private { les données membres sont presque toujours privées }
FPen: TPen; { donnée membre pour l’objet crayon }
FBrush: TBrush; { donnée membre pour l’objet pinceau }
ƒ
end;
implementation
ƒ
constructor TSampleShape.Create(AOwner: TComponent);
begin
inherited Create(AOwner); { appelez toujours le constructeur hérité }
Width := 65;
Height := 65;
FPen := TPen.Create; { construit le crayon }
FPen.OnChange := StyleChanged; { affecte la méthode à l’événement OnChange }
FBrush := TBrush.Create; { construit le pinceau }
FBrush.OnChange := StyleChanged; { affecte la méthode à l’événement OnChange }
end;
procedure TSampleShape.StyleChanged(Sender: TObject);
begin
Invalidate(True); { efface et redessine le composant }
end;
Ces modifications faites, le composant se redessine pour refléter tout changement
du crayon ou du pinceau.
property Ctl3D;
property Font;
property GridLineWidth;
property ParentColor;
property ParentFont;
property OnClick; { événements publiés }
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
end;
Il existe bien d’autres propriétés ne s’appliquant pas à un calendrier qui sont
publiables, par exemple la propriété Options qui permet à l’utilisateur de choisir les
lignes de la grille à dessiner.
Si vous installez le composant calendrier modifié dans la palette des composants
et l’utilisez dans une application, vous trouverez bien d’autres propriétés et
événements opérationnels. Nous allons maintenant commencer à ajouter de
nouvelles fonctionnalités au composant.
begin
inherited Create(AOwner); { appelle le constructeur hérité }
ColCount := 7; { toujours 7 jours/semaine }
RowCount := 7; { toujours 6 semaines plus les titres }
FixedCols := 0; { aucun libellé de ligne }
FixedRows := 1; { une ligne pour les noms de jour }
ScrollBars := ssNone; { pas de défilement nécessaire }
Options := Options - [goRangeSelect] + [goDrawFocusSelected]; {désactive la sélection
// d’intervalle}
end;
Le calendrier a dorénavant sept colonnes et sept lignes, avec la ligne de titre fixe
(ou qui ne défile pas).
Suivi de la date
Pour que le contrôle calendrier soit utile, les utilisateurs ainsi que les applications
doivent disposer d’un moyen de définir la date, le mois et l’année. Delphi stocke
les dates et les heures dans des variables de type TDateTime. TDateTime est une
représentation numérique encodée des dates et des heures particulièrement pratique
pour être manipulée par un programme mais peu commode à interpréter par un
utilisateur.
Vous pouvez donc stocker la date du calendrier sous une forme encodée et fournir
un accès direct à cette valeur lors de l’exécution, mais vous pouvez aussi fournir
les propriétés Day, Month et Year que l’utilisateur du composant peut définir lors
de la conception.
Le suivi de la date dans le calendrier comprend les traitements suivants :
• Stockage interne de la date
• Accès au jour, au mois et à l’année
• Génération des numéros de jours
• Sélection du jour en cours
Pour fournir un accès lors de la conception aux éléments jour, mois et année,
procédez de la façon suivante :
1 Déclarez les trois propriétés, en attribuant à chacune un numéro unique d’index :
type
TSampleCalendar = class(TCustomGrid)
public
property Day: Integer index 3 read GetDateElement write SetDateElement;
property Month: Integer index 2 read GetDateElement write SetDateElement;
property Year: Integer index 1 read GetDateElement write SetDateElement;
ƒ
2 Déclarez et écrivez les méthodes d’implémentation, définissant les différents
éléments pour chaque valeur d’index :
type
TSampleCalendar = class(TCustomGrid)
private
function GetDateElement(Index: Integer): Integer; { notez le paramètre Index }
procedure SetDateElement(Index: Integer; Value: Integer);
ƒ
function TSampleCalendar.GetDateElement(Index: Integer): Integer;
var
AYear, AMonth, ADay: Word;
begin
DecodeDate(FDate, AYear, AMonth, ADay); { éclate la date encodée en éléments }
case Index of
1: Result := AYear;
2: Result := AMonth;
3: Result := ADay;
else Result := -1;
end;
end;
procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);
var
AYear, AMonth, ADay: Word;
begin
if Value > 0 then { tous les éléments doivent être positifs }
begin
DecodeDate(FDate, AYear, AMonth, ADay); { récupère les éléments courants de la date}
case Index of { définit le nouvel élément selon l’index }
1: AYear := Value;
2: AMonth := Value;
3: ADay := Value;
else Exit;
end;
FDate := EncodeDate(AYear, AMonth, ADay); { encodage de la date modifiée }
Refresh; { mise à jour du calendrier visible }
end;
end;
Vous pouvez maintenant définir le jour, le mois et l’année du calendrier lors de
la conception à partir de l’inspecteur d’objets, ou à l’exécution à partir du code.
Bien que vous n’ayez pas encore ajouté le code pour dessiner les dates dans les
cellules, vous disposez maintenant de toutes les données nécessaires.
procedure TCalendar.PrevYear;
begin
DecodeDate(CalendarDate, -12), Year, Month, Day);
end;
N’oubliez pas d’ajouter les déclarations des nouvelles méthodes à la déclaration de
la classe.
Désormais, si vous créez une application qui utilise le composant calendrier, vous
pourrez facilement implémenter le passage de mois en mois ou d’année en année.
Déplacement de la sélection
Le comportement reçu en héritage d’une grille gère le déplacement de la sélection
en réponse aux touches de direction enfoncées ou aux clics de souris. Pour modifier
le jour sélectionné, vous devez modifier le comportement implicite.
Pour gérer les déplacements à l’intérieur du calendrier, vous devez surcharger la
méthode Click de la grille.
Lorsque vous surchargez une méthode telle que Click, en dépendance étroite avec
les interactions de l’utilisateur, vous devez pratiquement toujours inclure un appel à
la méthode reçue en héritage pour ne pas perdre le comportement standard.
Le code suivant est une méthode Click surchargée pour la grille calendrier.
N’oubliez pas d’ajouter la déclaration de Click à TSampleCalendar, en incluant après
la directive override.
procedure TSampleCalendar.Click;
var
TempDay: Integer;
begin
inherited Click; { n’oubliez pas d’appeler la méthode héritée ! }
TempDay := DayNum(Col, Row); { récupère le numéro du jour de la cellule cliquée }
if TempDay <> -1 then Day := TempDay; { change le jour s’il est valide }
end;
Pour déterminer si une cellule est sélectionnable, vous devez surcharger la méthode
SelectCell de la grille.
SelectCell est une fonction qui accepte deux paramètres ligne et colonne et qui
renvoie une valeur booléenne indiquant si la cellule spécifiée est sélectionnable.
Vous pouvez surcharger SelectCell pour qu’elle renvoie false si la cellule ne contient
pas une date valide :
function TSampleCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
if DayNum(ACol, ARow) = -1 then Result := False { -1 indique une date incorrecte }
else Result := inherited SelectCell(ACol, ARow); { sinon, utilise la valeur héritée }
end;
Désormais, si l’utilisateur clique sur une cellule vide ou tente de s’y déplacer à
l’aide des touches de direction, le calendrier ne modifie pas la sélection en cours.
begin
MyMouseDown := OnMouseDown;
if Assigned(MyMouseDown then MyMouseDown(Self, Button, Shift, X, Y);
end;
end;
Lorsque MouseDown répond à un message indiquant la manipulation de la
souris, la méthode MouseDown héritée est appelée uniquement si la propriété
ReadOnly du contrôle est False et si l’objet lien de données est en mode édition,
c’est-à-dire si le champ peut être modifié. Si le champ ne peut être modifié, le
code mis par le programmeur dans le gestionnaire de l’événement
OnMouseDown, s’il en existe un, est exécuté.
implementation
procedure Register;
begin
RegisterComponents('Samples', [TAboutBoxDlg]);
end;
end.
Pour l’instant, le nouveau composant possède uniquement les fonctionnalités
intégrées à TComponent. C’est le composant non visuel le plus simple. Dans la
section suivante, vous allez créer l’interface entre le composant et la boîte de
dialogue.
Les propriétés d’un composant enveloppe sont sensiblement plus simples à écrire
que celles d’un composant standard. Souvenez-vous que vous ne faites que créer
des données permanentes que l’enveloppe et la boîte de dialogue peuvent
échanger. En définissant ces données sous la forme de propriétés, vous donnez
aux développeurs la possibilité de définir des données au moment de la
conception qui, lors de l’exécution, seront transmises par l’enveloppe à la boîte
de dialogue.
La déclaration d’une propriété d’interface nécessite deux ajouts à la déclaration
de classe du composant :
• Un champ de classe privé qui est une variable utilisée par l’enveloppe pour
stocker la valeur de la propriété
• La déclaration published de la propriété elle-même qui indique son nom et le
champ à utiliser pour le stockage.
De telles propriétés d’interface n’ont pas besoin de méthodes d’accès. Elles
accèdent directement aux données stockées. Par convention, le champ qui stocke
la valeur de la propriété porte le même nom que la propriété, mais précédé de la
lettre F. Le champ et la propriété doivent avoir le même type.
Par exemple, la déclaration d’une propriété d’interface de type entier appelée
Year, est la suivante :
type
TMyWrapper = class(TComponent)
private
FYear: Integer; { donnée membre pour les données de la propriété Year}
published
property Year: Integer read FYear write FYear; { la propriété et son stockage }
end;
S’agissant de votre boîte A propos de, vous devez disposer de quatre propriétés
de type string pour le nom du produit, les informations de version, les
informations de copyright et les commentaires éventuels.
type
TAboutBoxDlg = class(TComponent)
private
FProductName, FVersion, FCopyright, FComments: string; { déclare les
//données membres}
published
property ProductName: string read FProductName write FProductName;
property Version: string read FVersion write FVersion;
property Copyright: string read FCopyright write FCopyright;
property Comments: string read FComments write FComments;
end;
Si vous installez votre composant dans la palette des composants et si vous le
placez dans une fiche, vous pourrez définir les propriétés, et ces valeurs
apparaîtront de façon permanente dans la fiche. Ainsi, lors de l’exécution de la
boîte de dialogue qu’il enveloppe, le composant pourra les utiliser.
Test du composant
Une fois le composant boîte de dialogue installé, vous pouvez l’utiliser comme
n’importe quelle autre boîte de dialogue commune, en le plaçant sur une fiche et
en l’exécutant. Un moyen rapide de vérifier le fonctionnement de la boîte A
propos de consiste à ajouter un bouton de commande dans une fiche et à
exécuter la boîte de dialogue lorsque l’utilisateur clique sur ce bouton.
Par exemple, si vous avez créé une boîte de dialogue A propos de, et si vous
l’avez ajouté à la palette des composants, vous pouvez tester son fonctionnement
en suivant les étapes ci-dessous :
1 Créez un nouveau projet.
2 Placez un composant A propos de dans la fiche principale.
3 Placez un bouton de commande dans la fiche.
4 Double-cliquez sur le bouton de commande pour créer un gestionnaire
d’événements vide.
5 Dans le gestionnaire d’événements, entrez la ligne de code suivante :
AboutBoxDlg1.Execute;
6 Exécutez l’application.
V
Développement
Part V
d’applications COM
Les chapitres de cette partie présentent les concepts nécessaires à la construction
d’applications COM : contrôleurs Automation, serveurs Automation, contrôles
ActiveX et applications MTS.
Remarque Toutes les éditions de Delphi prennent en charge les contrôleurs Automation,
mais vous avez besoin de l’édition Professionnelle ou Entreprise pour créer des
serveurs.
Présentation Chapter 44
44
des technologies COM
Delphi fournit des experts et des classes qui facilitent l’implémentation
d’applications basées sur COM (Component Object Model) de Microsoft. Grâce à
ces experts, vous pouvez créer des classes et des composants basés sur COM,
que vous utiliserez dans des applications, comme des objets COM sophistiqués,
des serveurs et des clients Automation (contrôleurs), des contrôles ActiveX, des
pages Active Server ou des fiches ActiveForms.
COM est un modèle de composant logiciel indépendant du langage, conçu par
Microsoft pour permettre l’interaction entre les composants logiciel et les
applications. Microsoft a étendu cette technologie avec ActiveX, qui est
essentiellement utilisée pour le développement Intranet.
L’aspect majeur de COM est qu’il permet la communication entre les
composants, entre les applications et entre clients et serveurs par le biais
d’interfaces clairement définies. Les interfaces représentent pour les clients un
moyen d’obtenir à l’exécution les fonctionnalités prises en charge par un
composant COM. Pour que votre composant fournisse des fonctionnalités
supplémentaires, il suffit d’ajouter une autre interface à ces fonctionnalités.
Les applications peuvent accéder aux composants COM et aux interfaces
correspondantes s’ils figurent sur le même ordinateur que les applications ou,
s’ils figurent sur un autre ordinateur du réseau, à l’aide d’un mécanisme appelé
Distributed COM ou DCOM. Pour plus d’informations sur les clients, les
serveurs et les interfaces, voir, “Composantes d’une application COM,” à la
page 44-3.
Ce chapitre présente les concepts généraux de la technologie sur laquelle
s’appuient l’Automation et les contrôles ActiveX. Les chapitres suivants traiteront
en détail de la création d’objets Automation et de contrôles ActiveX dans Delphi.
Extensions de COM
COM a évolué et a été étendu au-delà des services de base. COM sert de
fondement à d’autres technologies, comme l’Automation, aux contrôles ActiveX,
aux pages Active Server et aux documents Active. Pour plus de détails, voir
“Extensions de COM” à la page 44-9.
En outre, vous pouvez créer un objet COM qui fonctionne dans l’environnement
MTS (Microsoft Transaction Server). MTS est un système de traitement des
transactions basé sur les composants, permettant de construire, déployer et gérer
de grosses applications serveur intranet et Internet. Bien que MTS ne fasse pas
partie de l’architecture COM, il a été conçu pour étendre les capacités de COM
dans un vaste environnement distribué. Pour plus d’informations sur MTS, voir
chapitre 50, “Création des objets MTS.”
Delphi fournit des experts permettant d’implémenter facilement des applications
qui incorporent toutes ces technologies dans l’environnement Delphi. Pour plus
de détails, voir “Implémentation des objets COM à l’aide d’experts” à la
page 44-18
Interface COM Le moyen par lequel un objet expose ses services aux
clients. Un objet COM fournit une interface pour chaque
ensemble de méthodes (fonctions membre) et de propriétés
(membres de données et/ou contenu) connexes.
Serveur COM Un module, EXE, DLL ou OCX, contenant le code d’un
objet COM. Les implémentations d’objets résident sur les
serveurs. Un objet COM implémente une ou plusieurs
interfaces.
Client COM Le code appelant les interfaces afin d’obtenir du serveur les
services demandés. Les clients savent ce qu’ils veulent
obtenir du serveur (via l’interface) ; les clients ne savent pas
comment en interne le serveur fournit les services. Le client
COM le plus courant à implémenter est un contrôleur
Automation. Delphi facilite le processus de création de
client en vous permettant d’installer des serveurs COM (tel
qu’un document Word ou une diapositive Powerpoint) en
tant que composants sur la palette de composants.
Interfaces COM
Les clients COM communiquent avec des objets par le biais d’interfaces COM. Les
interfaces sont des groupes de routines, liées par la logique ou par la sémantique,
qui assurent la communication entre le fournisseur d’un service (objet serveur) et
ses clients. Voici la représentation standard d’une interface COM :
Figure 44.1 Une interface COM
Par exemple, chaque objet COM implémente l’interface de base, IUnknown, qui
indique au client les interfaces disponibles sur le client.
Les objets peuvent avoir plusieurs interfaces, où chacune implémente une
fonctionnalité. L’interface est le moyen de mettre à disposition du client le
service fourni par l’objet, sans lui donner les détails de l’implémentation sur la
façon dont ce service est fourni.
Les aspects majeurs des interfaces COM sont les suivants :
• Une fois publiées, les interfaces sont immuables ; c’est-à-dire qu’elles ne
changent plus. Une interface permet d’accéder à un ensemble précis de
fonctions. Les fonctionnalités supplémentaires sont fournies par le biais
d’interfaces supplémentaires.
Les clients obtiennent des pointeurs sur d’autres interfaces via la méthode
QueryInterface de IUnknown. QueryInterface connaît chaque interface de l’objet
serveur et peut donner au client un pointeur vers l’interface demandée. Lorsqu’il
reçoit un pointeur vers une interface, le client est assuré de pouvoir appeler
n’importe quelle méthode de l’interface.
Les objets contrôlent leur propre durée de vie grâce aux méthodes AddRef et
Release de IUnknown, qui sont de simples méthodes de décompte de références.
Tant que le décompte de références est différent de zéro, l’objet reste en
mémoire. Dès qu’il atteint zéro, l’implémentation de l’interface peut en toute
sécurité disposer du ou des objets sous-jacents.
Serveurs COM
Un serveur COM est une application ou une bibliothèque qui fournit des
services à une application ou bibliothèque client. Un serveur COM est constitué
d’un ou de plusieurs objets COM, un objet COM étant un ensemble de
propriétés (données membre ou contenu) et de méthodes (fonctions membre).
Les clients ne savent pas comment l’objet COM effectue son service ;
l’implémentation de l’objet est encapsulée. Un objet met ses services à disposition
par le biais de ses interfaces comme décrit précédemment.
En outre, les clients n’ont pas besoin de savoir où réside l’objet COM. COM
fournit un accès transparent quel que soit l’emplacement de l’objet.
Quand il demande un service à un objet COM, le client transmet un
identificateur de classe (CLSID) à COM. Un CLSID est juste un GUID qui
référence un objet COM. COM utilise ce CLSID pour localiser l’implémentation
appropriée du serveur, amène le code en mémoire, et fait créer par le serveur
une instance de l’objet pour le client. Un serveur COM doit donc fournir un
objet fabricant de classe (IClassFactory) qui crée sur demande des instances
d’objet. Le CLSID est basé sur le GUID de l’interface.
En général, un serveur COM doit effectuer ceci :
• Recenser des entrées dans le registre système pour associer le module serveur
à l’identificateur de classe (CLSID).
• Implémenter un objet fabricant de classe, qui est un type d’objet spécial qui
fabrique un autre objet d’un CLSID particulier.
• Exposer le fabricant d’objet à COM.
• Fournir un mécanisme de déchargement grâce auquel un serveur qui ne sert
pas de client pourra être supprimé de la mémoire.
Remarque Les experts de Delphi automatisent la création des objets et des serveurs COM
comme décrit dans “Implémentation des objets COM à l’aide d’experts” à la
page 44-18.
Serveur hors Une autre application (EXE) s’exécutant dans un espace processus
processus (ou différent mais sur la même machine que le client. Par exemple, une
serveur local) feuille de calcul Excel incorporée dans un document Word
constitue deux applications distinctes tournant sur la même
machine.
Le serveur local utilise COM pour communiquer avec le client.
Serveur distant Une DLL ou une autre application s’exécutant sur une machine
différente de celle du client. Par exemple, une application Delphi
de base de données connectée à un serveur d’application sur une
autre machine du réseau.
Le serveur distant utilise des interfaces COM distribuées (DCOM)
pour communiquer avec le serveur d’application.
Comme illustré dans la figure suivante, pour les serveurs en processus, les
pointeurs sur les interfaces de l’objet sont dans le même espace processus que le
client, et COM fait des appels directs dans l’implémentation de l’objet.
Figure 44.3 Serveurs en processus
Comme illustré dans la figure suivante, quand le processus est soit différent, soit
sur une autre machine, COM utilise un proxy pour initier les appels de
procédure distants. Le proxy réside dans le même processus que le client, de
sorte que vu du client, tous les appels à des interfaces semblent pareils. Le proxy
intercepte l’appel du client et le transmet là où l’objet réel s’exécute. Le
mécanisme qui permet aux clients d’accéder aux objets d’un espace processus
différent, ou même d’une machine différente, comme s’ils se trouvaient dans leur
propre processus, est appelé le marshaling.
La différence entre les serveurs hors processus et distants est le type de
communication inter-processus utilisé. Le proxy utilise COM pour communiquer
avec un serveur hors processus et COM distribué (DCOM) pour communiquer
avec une machine distante.
Le mécanisme du marshaling
Le marshaling est le mécanisme qui permet à un client de faire des appels aux
fonctions de l’interface d’objets distants qui se trouvent dans un autre processus
ou sur une autre machine. Le marshaling
• Prend un pointeur d’interface dans le processus du serveur et rend un
pointeur de proxy disponible au code dans le processus du client.
• Prend les arguments d’un appel à l’interface passés depuis le client et les
place dans l’espace processus de l’objet distant.
Pour tout appel à l’interface, le client met les arguments sur une pile et émet un
appel à une fonction via le pointeur d’interface. Si l’appel à l’objet n’est pas en
processus, il est passé au proxy. Celui-ci compresse les arguments dans un
paquet de marshaling et transmet la structure à l’objet distant. Le stub de l’objet
décompresse le paquet, place les arguments sur la pile et appelle
l’implémentation de l’objet. L’objet recrée l’appel du client dans son propre
espace d’adressage.
Le type de marshaling dépend de ce que l’objet COM implémente. Les objets
peuvent utiliser le mécanisme de marshaling standard fourni par l’interface
IDispatch. C’est un mécanisme de marshaling générique qui permet la
communication via un appel standard à une procédure distante (RPC). Pour plus
de détails sur l’interface IDispatch, voir chapitre 47, “Création d’un serveur
Automation.”
Remarque MTS (Microsoft Transaction Server) apporte un support supplémentaire pour les
objets distants. Pour plus de détails, voir chapitre 50, “Création des objets MTS”.
Clients COM
Il est important de concevoir une application COM dans laquelle les clients
peuvent interroger les interfaces d’un objet pour déterminer ce que celui-ci peut
offrir. Les objets serveur ne sont pas concernés par l’utilisation qu’en fait le
client. Celui-ci connaît ce qu’un objet peut fournir via ses interfaces. En outre, les
clients n’ont pas besoin de savoir comment (ou même où) un objet fournit ses
services ; c’est le problème de l’objet de fournir le service publié par le biais de
l’interface.
Un client COM typique est le contrôleur Automation. Le contrôleur Automation
est la partie de l’application qui a la vue la plus complète des objectifs de
l’application. Il connaît le type d’information dont elle a besoin des divers objets
du serveur et il demande les services lorsque c’est nécessaire.
Delphi facilite le développement d’un contrôleur Automation en permettant
d’importer la bibliothèque de types d’un serveur Automation et de l’installer sur la
palette de composants.
Pour plus de détails sur la création d’un contrôleur Automation, voir chapitre 46,
“Création d’un contrôleur Automation”.
Extensions de COM
COM a été initialement conçu pour fournir une fonctionnalité de communication
de base et permettre l’enrichissement de cette fonctionnalité via des extensions.
COM lui-même a étendu sa fonctionnalité première en définissant des ensembles
spécialisés d’interfaces couvrant des besoins spécifiques.
ActiveX est une technologie qui permet aux composants COM, particulièrement
les contrôles, d’être plus compacts et plus efficaces. Cela est notamment
nécessaire pour les contrôles destinés aux applications Intranet qui doivent être
téléchargées par un client pour pouvoir être utilisées.
Microsoft incorpore au modèle COM certaines des technologies MTS qui
permettront de construire de complexes applications Internet et intranet. La
phase suivante de COM, qui incorpore aussi de nouvelles fonctionnalités, est
actuellement appelée “COM+” (COM Plus) et devrait être disponible en même
temps que Windows 2000.
Le tableau suivant est un résumé des extensions de services que COM fournit
actuellement. Les sections suivantes décrivent ces services en détail.
Le diagramme page suivante montre les relations entre les extensions de COM et
la façon dont elles dérivent de COM.
Contrôles ActiveX
Les contrôles ActiveX sont des contrôles visuels qui s’exécutent seulement dans
des serveurs en processus, et peuvent être incorporés dans une application
conteneur de contrôles ActiveX. Ce ne sont pas eux-mêmes des applications
complètes, mais de simples contrôles OLE préfabriqués réutilisables dans
diverses applications. Les contrôles ActiveX utilisent l’Automation pour exposer
leurs propriétés, méthodes et événements. Leurs fonctionnalités incluent la
capacité à déclencher des événements, la liaison aux sources de données et la
gestion de licence.
De plus en plus fréquemment, les contrôles ActiveX s’utilisent dans un site Web
comme objets interactifs placés dans une page Web. Ainsi, ActiveX est devenu
un standard particulièrement destiné à des contenus interactifs pour le Web, y
compris l’utilisation de documents ActiveX employés pour visualiser des
documents non HTML via un navigateur Web. Pour plus d’informations sur la
technologie ActiveX, voir le site Web de Microsoft.
Les experts de Delphi facilitent la création des contrôles ActiveX. Pour plus
d’informations sur la création et l’utilisation de ces types d’objets, voir
chapitre 48, “Création d’un contrôle ActiveX”.
Bibliothèques de types
Les bibliothèques de types offrent un moyen d’obtenir davantage d’informations
de type sur un objet que les interfaces de l’objet. Les bibliothèques de types
contiennent les informations nécessaires sur les objets et leurs interfaces, comme
les interfaces associées à tels objets (étant donné le CLSID), les fonctions membre
de chaque interface et les arguments requis par ces fonctions.
Vous pouvez obtenir les informations de type en interrogeant une instance d’un
objet pendant qu’elle s’exécute ou, en chargeant et en lisant les bibliothèques de
types. Grâce à ces informations, vous pouvez implémenter un client qui utilise
un objet souhaité, en sachant exactement les fonctions membre dont vous avez
besoin, et ce qu’il faut passer à ces fonctions.
Les clients des serveurs Automation et des contrôles ActiveX s’attendent à
trouver ces informations de type. Les experts Automation et ActiveX génèrent
automatiquement une bibliothèque de types. Vous pouvez voir ou modifier ces
informations de type en utilisant l’éditeur de bibliothèques de types comme
décrit dans le chapitre 49, “Utilisation des bibliothèques de types”.
Cette section décrit le contenu d’une bibliothèque de types, comment la créer,
quand l’utiliser et comment y accéder. Pour les développeurs souhaitant partager
des interfaces à travers divers langages, la section se termine par des suggestions
sur l’utilisation des outils de gestion de bibliothèques de types.
Interface Description
ITypeLib Fournit des méthodes pour accéder à la description d’une bibliothèque
de types.
ITypeInfo Fournit la description de chaque objet d’une bibliothèque de types. Par
exemple, un navigateur utilise cette interface pour extraire des
informations sur les objets de la bibliothèque de types.
ITypeComp Fournit un moyen rapide d’accéder aux informations dont le
compilateur a besoin lors de la liaison avec une interface.
Documents Active
Les documents Active (appelés auparavant documents OLE) sont un ensemble de
services COM supportant la liaison et l’incorporation, le glisser-déplacer et
l’édition visuelle. Les documents Active intègrent de façon transparente des
données ou des objets de différents formats, par exemple des clips sonores, des
feuilles de calcul, du texte et des images.
Contrairement aux contrôles ActiveX, les documents Active ne sont pas limités
aux serveurs en processus ; ils peuvent être utilisés dans des applications inter-
processus.
A la différence des objets Automation, qui ne sont presque jamais visuels, les
objets document Active peuvent être visuellement actifs dans une autre
application. Ils sont associés à deux types de données : les données de
représentation utilisées pour l’affichage visuel à l’écran ou sur un périphérique
de sortie et les données natives utilisées pour modifier l’objet.
Les objets document Active peuvent être des conteneurs ou des serveurs de
documents. Bien que Delphi ne fournisse pas d’expert pour créer
automatiquement des documents Active, vous pouvez utiliser la classe
TOleContainer de la VCL pour supporter la liaison et l’incorporation dans les
documents Active existants.
Vous pouvez aussi utiliser TOleContainer comme base d’un conteneur de
document Active. Pour créer des objets pour les serveurs de documents Active,
utilisez une des classes de base COM de la VCL et implémentez les interfaces
appropriées à ce type d’objet, en fonction des services que l’objet doit gérer. Pour
plus d’informations sur la création et l’utilisation de serveurs de documents
Active, voir le site Web Microsoft.
Remarque Bien que la spécification des documents Active contienne une gestion intégrée du
marshaling des applications à processus croisé, les documents Active ne
s’exécutent pas sur des serveurs distants car les types qu’ils utilisent (handles de
fenêtre, de menu, etc.) sont spécifiques à un système sur une machine donnée.
Comme le montre la figure 44.7, pour les objets Automation, l’expert implémente
IUnknown et IDispatch, qui fournissent le marshaling automatique.
Figure 44.7 Interfaces d’un objet Automation
Comme le montre la figure 44.8, pour les objets contrôles ActiveX, l’expert
implémente toutes les interfaces requises par les contrôles ActiveX : IUnknown,
IDispatch, IOleObject, IOLEControl, etc. Pour obtenir la liste complète des
interfaces, reportez-vous à la page de référence de l’objet TActiveXControl.
Tableau 44.2 Experts Delphi pour l’implémentation des objets COM, Automation et
ActiveX (suite)
Interfaces
Expert implémentées Ce que fait l’expert
ActiveForm Mêmes interfaces que Effectue les actions de l’expert contrôle
contrôle ActiveX ActiveX, plus :
Implémente les propriétés, méthodes et
événements pour toutes les interfaces de
TActiveXControl.
Vous laisse avec une fiche pour que vous
puissiez concevoir une application.
Objet Active Server IUnknown, IDispatch Effectue les actions d’un expert objet
Automation (décrit plus haut) et génère une
page .ASP qui peut être chargée dans un
navigateur Web. Vous laisse dans l’éditeur de
bibliothèques de types pour que vous puissiez
modifier les propriétés et les méthodes de
l’objet, si nécessaire.
Si vous affectez aux méthodes d’événement de
niveau page le type Active Server, ce dernier
implémente OnStartPage et OnEndPage
automatiquement.
Bibliothèque Aucune, par défaut Crée une nouvelle DLL serveur ActiveX ou
ActiveX COM et expose les fonctions d’exportation
nécessaires.
Page de propriétés IUnknown, Crée une nouvelle page de propriétés que vous
IPropertyPage pouvez concevoir dans le concepteur de fiche.
Bibliothèque Aucune, par défaut Crée une nouvelle bibliothèque de types et
de types l’associe au projet actif.
objet MTS Les méthodes Ajoute une nouvelle unité au projet en cours
d’interface contenant la définition de l’objet MTS, afin que
IObjectControl ainsi que les clients puissent accéder à ce serveur dans
Activate, Deactivate, et l’environnement d’exécution MTS. Vous laisse
CanBePooled. dans l’éditeur de bibliothèque de types pour
que vous puissiez modifier les propriétés et les
méthodes de l’objet, si nécessaire.
Si vous voulez, vous pouvez ajouter d’autres objets COM (ou refaire une
implémentation existante). Pour fournir une nouvelle interface, créez un
descendant de l’interface IDispatch et implémentez les méthodes nécessaires. Pour
implémenter à nouveau une interface, créez un descendant de cette interface et
modifiez ce descendant.
Interfaces Spécifiez les noms des interfaces COM que cet objet COM doit
implémentées implémenter.
Description Entrez la description de l’objet COM que vous êtes en train de
créer.
Inclure la Cochez cette case pour générer une bibliothèque de types pour
bibliothèque de cet objet. Une bibliothèque de types contient les informations
types qui vous permettent d’exposer toute interface de l’objet, ainsi
que ses méthodes et ses propriétés, aux applications client. Le
fait de cocher cette case active automatiquement la case
Marquer l’interface OleAutomation.
Marquer Cochez cette case pour activer le code de marshaling généré
l’interface quand vous créez une bibliothèque de types. COM sait
OleAutomation comment effectuer un marshaling de tous les types compatibles
Automation dans la bibliothèque de types et peut définir les
proxy et stubs de façon à transmettre des paramètres aux
serveurs hors processus (.EXE). Pour plus d’informations, voir
“Le mécanisme du marshaling” à la page 44-8.
Instanciation Signification
Interne L’objet ne peut être créé que de manière interne. Une application externe
ne peut pas créer d’instance de l’objet directement. Par exemple, une
application de traitement de texte peut avoir un objet document qui ne
peut être créé qu’en appelant une méthode de l’application qui peut
créer l’objet document.
Instance unique Autorise uniquement une seule interface COM pour chaque exécutable
(application), de sorte que la création de plusieurs instances entraîne la
création de plusieurs applications. Instance unique spécifie qu’aussitôt
qu’une application s’est connectée à l’objet, celui-ci est retiré de la vue
publique afin qu’aucune autre application ne puisse s’y connecter. Cette
option est souvent utilisée pour les applications MDI (interface à
documents multiples). Lorsqu’un client requiert les services d’un objet à
instance unique, toutes les demandes sont gérées par le même serveur.
Par exemple, chaque fois qu’un utilisateur demande d’ouvrir un nouveau
document dans une application de traitement de texte, le nouveau
document s’ouvre habituellement dans le même processus d’application.
Instance multiple Spécifie que plusieurs applications peuvent se connecter à l’objet. Chaque
fois qu’un client demande un service, une nouvelle instance du serveur
est invoquée. (C’est-à-dire qu’il peut y avoir plusieurs instances dans un
seul exécutable.) Chaque fois qu’un utilisateur essaie d’ouvrir
l’Explorateur de Windows, un Explorateur distinct est créé.
2 Sélectionnez tous les objets que vous venez d’ajouter sur la page et
choisissez Cacher.
3 Choisissez l’option de suppression. La page Serveurs disparaît.
2 Retournez dans le paquet Composants Serveur automation exemple Borland :
1 Choisissez Composant|Installer des paquets.
2 Cliquez sur Ajouter, naviguez jusqu’au répertoire BIN de Delphi et
sélectionnez le paquet Composants Serveur automation exemple Borland.
Choisissez Ouvrir.
Nom CoClasse Spécifiez la classe dont vous voulez exposer les propriétés et
les méthodes aux applications client. (Delphi fait précéder ce
nom d’un T.)
Instancie Spécifiez un mode d’instanciation pour indiquer comment
lancer le serveur Automation. Pour plus d’informations, voir
“Types d’instanciation des objets COM” à la page 45-3.
Remarque : quand l’objet Automation est utilisé uniquement
comme serveur en processus, l’instanciation est ignorée.
Modèle de thread Choisissez le modèle de thread pour indiquer comment les
applications client peuvent appeler l’interface de l’objet. C’est
le modèle de thread que vous validez pour l’implémentation
de l’objet Automation. Pour plus d’informations sur les
modèles de thread, voir “Choix d’un modèle de thread” à la
page 45-4.
Remarque : le modèle de thread choisi détermine la façon
dont l’objet est recensé. Vous devez vous assurer que
l’implémentation de l’objet est conforme au modèle
sélectionné.
Créer le code Cochez cette case pour demander à l’expert d’implémenter
de support une interface distincte pour la gestion des événements de
d’événement l’objet Automation.
Une fois cette procédure terminée, une nouvelle unité est ajoutée au projet en
cours, elle contient la définition de l’objet Automation. De plus, l’expert ajoute
au projet une bibliothèque de types et l’ouvre. Vous pouvez alors exposer les
propriétés et les méthodes de l’interface via la bibliothèque de types comme
indiqué plus bas.
L’objet Automation implémente une interface duale, qui supporte à la fois la
liaison immédiate (à la compilation) via la vtable et la liaison différée (à
l’exécution) via l’interface IDispatch. Pour plus d’informations, voir “Interfaces
duales” à la page 47-7.
Interfaces Automation
Les experts de Delphi implémentent par défaut une interface duale, ce qui
signifie que l’objet Automation supporte à la fois :
• La liaison différée à l’exécution, via l’interface IDispatch. C’est l’interface de
répartition ou dispinterface.
• La liaison immédiate à la compilation, qui s’effectue via un appel direct à
l’une des fonctions membre de la table des fonctions virtuelles (VTable) de
l’objet. C’est l’interface personnalisée.
Interfaces duales
Une interface duale est à la fois une interface personnalisée et une dispinterface.
Elle est implémentée en tant qu’interface vtable COM qui dérive de IDispatch.
Pour les contrôleurs qui accèdent à l’objet uniquement pendant l’exécution, la
dispinterface est disponible. Pour les objets qui peuvent tirer profit de la liaison
à la compilation, c’est l’interface VTable la plus efficace qui est utilisée.
Les interfaces duales offrent les avantages combinés des interfaces VTable et des
dispinterfaces :
• Pour les interfaces VTable, le compilateur fait une vérification de type et
fournit des messages d’erreurs plus informatifs.
• Pour les contrôleurs Automation qui ne peuvent pas obtenir d’information de
type, la dispinterface fournit l’accès à l’objet à l’exécution.
• Pour les serveurs en processus, vous bénéficiez d’un accès rapide via les
interfaces VTable.
• Pour les serveurs hors processus, COMeffectue le marshaling des données à la
fois pour les interfaces VTable et pour les dispinterfaces. COM fournit une
implémentation proxy/stub générique qui peut réaliser le marshaling de
l’interface en fonction des informations contenues dans une bibliothèque de
types. Pour plus d’informations sur le marshaling, voir Marshaling des
données,” à la page 47-9.
Le diagramme page suivante représente une interface IMyInterface dans un objet
qui supporte une interface duale nommée IMyInterface. Les trois premières
entrées de la VTable d’une interface duale font référence à l’interface IUnknown,
les quatre suivantes font référence à l’interface IDispatch, les autres sont des
entrées COM pour l’accès direct aux membres de l’interface personnalisée.
Interfaces de répartition
Les contrôleurs Automation sont des clients qui utilisent l’interface COM
IDispatch pour accéder aux objets du serveur COM. Le contrôleur doit d’abord
créer l’objet, puis demander à l’interface IUnknown de l’objet un pointeur sur son
interface IDispatch. IDispatch garde en interne la trace des méthodes et des
propriétés par le biais d’un identificateur de répartition (dispID), qui est un
numéro d’identification propre à chaque membre interface. Par IDispatch, un
contrôleur récupère les informations de type de l’objet pour l’interface de
répartition, puis associe le nom des membres interface aux dispID spécifiques.
Ces dispID sont accessibles à l’exécution et les contrôleurs y accèdent en
appelant la méthode GetIDsOfNames de IDispatch.
Lorsqu’il connaît le dispID, le contrôleur peut appeler la méthode Invoke de
IDispatch pour exécuter le code requis (propriété ou méthode), en regroupant les
paramètres de la propriété ou de la méthode dans l’un des paramètres Invoke.
Invoke a une signature fixe définie lors de la compilation, qui lui permet
d’accepter des arguments variés lors de l’appel d’une méthode d’interface.
L’implémentation de l’objet automation de Invoke doit alors dégrouper les
paramètres, appeler la propriété ou la méthode et gérer les éventuelles erreurs.
Lorsque la propriété ou la méthode revient, l’objet retransmet la valeur renvoyée
au contrôleur.
Cette procédure est appelée liaison différée car le contrôleur se lie à la propriété
ou à la méthode lors de l’exécution de l’application plutôt que lors de sa compilation.
Interfaces personnalisées
Les interfaces personnalisées sont des interfaces définies par l’utilisateur qui
permettent aux clients d’appeler les méthodes de l’interface en fonction de leur
ordre dans la VTable et du type des arguments. La VTable contient les adresses
de toutes les propriétés et méthodes qui sont membres de l’objet, y compris les
fonctions membre des interfaces qu’il supporte. Si l’objet ne supporte pas
IDispatch, les entrées correspondant aux membres des interfaces personnalisées
de l’objet suivent immédiatement celles des membres de IUnknown.
Si l'objet possède une bibliothèque de types, vous pouvez accéder à l'interface
personnalisée via sa disposition VTable, que vous pouvez obtenir à l'aide de
l'éditeur de bibliothèque de types. Si l'objet possède une bibliothèque de types et
gère IDispatch, un client peut aussi obtenir les dispID de l’interface IDispatch et
se lier directement à un déplacement de la VTable. L’importateur de la
bibliothèque de types de Delphi (TLIBIMP) extrait les dispIDs à l’importation, ce
qui évite aux clients qui utilisent les enveloppes de dispinterfaces d’appeler
GetIDsOfNames; ces informations figurent déjà dans le fichier _TLB file. Toutefois,
les clients doivent appeler Invoke.
• Les types interface définis dans une bibliothèque de types qui sont sécurisés
Automation OLE, c’est-à-dire dérivés de IDispatch et contenant seulement des
types compatibles Automation OLE.
• Les types dispinterface définis dans une bibliothèque de types.
• IFont, IStrings et IPicture. Les objets utilitaires doivent être instanciés pour que
correspondent
• un IFont à un TFont
• un IStrings à un TStrings
• un IPicture à un TPicture
Les experts contrôle ActiveX et ActiveForm créent automatiquement ces objets
utilitaires lorsque c’est nécessaire. Pour utiliser les objets utilitaires, appelez
respectivement les routines globales GetOleFont, GetOleStrings, GetOlePicture.
Marshaling personnalisé
Typiquement, vous utiliserez le marshaling automatique dans les serveurs hors
processus et distants parce que c’est le plus simple -- COM fait le travail à votre
place. Cependant, vous pouvez décider de fournir un marshaling personnalisé si
vous pensez que ses performances seront supérieures.
Contrôle VCL
Un contrôle ActiveX dans Delphi est simplement un contrôle VCL qui a été
rendu accessible aux applications et aux objets supportant les contrôles ActiveX.
Lorsque vous créez un contrôle ActiveX, vous devez d’abord concevoir ou
choisir le contrôle VCL à partir duquel vous allez le construire.
Remarque Les contrôles disponibles dans la liste de l’expert sont dérivés de TWinControl.
Certains contrôles, comme EditControl, sont recensés comme contrôles Non
ActiveX et n’apparaissent donc pas dans la liste.
Bibliothèque de types
Une bibliothèque de types contient les définitions des types du contrôle ; elle est
créée automatiquement par l’expert contrôle ActiveX. Ces informations de types,
qui fournissent plus de détails que l’interface, représentent pour les contrôles un
moyen de publier leurs services aux applications hôtes. Lorsque vous concevez
votre contrôle, les informations de la bibliothèque de types sont stockées dans un
fichier portant l’extension .TLB et un fichier Pascal correspondant contient les
conversions Pascal. Lorsque vous construisez le contrôle ActiveX, les
informations de la bibliothèque de types sont automatiquement compilées dans
la DLL du contrôle ActiveX en tant que ressource.
Page de propriétés
La page de propriétés permet à l’utilisateur d’un contrôle de voir et de modifier
ses propriétés. Vous pouvez grouper plusieurs propriétés sur une page, ou
utiliser une page pour fournir une interface de type dialogue à une propriété.
Pour savoir comment créer des pages de propriétés, voir “Création d’une page
de propriétés pour un contrôle ActiveX” à la page 48-14.
Nom de classe VCL Cette option est estompée puisque les fiches ActiveForms
sont toujours basées sur TActiveForm.
Nouveau nom L’expert fournit un nom par défaut que les clients utiliseront
pour identifier votre contrôle ActiveX. Changez ce nom si
vous voulez fournir un autre nom de classe OLE.
Unité L’expert fournit un nom par défaut à l’unité contenant le
implémentation code d’implémentation du comportement du contrôle
ActiveX. Acceptez ce nom par défaut ou tapez-en un autre.
Projet L’expert fournit un nom par défaut au projet de bibliothèque
ActiveX pour votre contrôle ActiveX, si aucun projet en
cours n’est ouvert. Si une bibliothèque ActiveX est ouverte,
cette option est désactivée.
Modèle de thread Choisissez le modèle de thread pour indiquer comment les
applications client appellent l’interface de votre contrôle.
C’est le modèle de thread que vous validez pour
l’implémentation dans le contrôle. Pour plus d’informations
sur les modèles de thread “Choix d’un modèle de thread” à
la page 45-4.
Remarque : le modèle de thread choisi détermine la façon
dont l’objet est recensé. Vous devez vous assurer que
l’implémentation de l’objet est conforme au modèle
sélectionné.
Recenser le contrôle Cochez cette case pour activer la licence des contrôles ActiveX
que vous concevez et distribuez (à moins que les contrôles ne
soient distribués gratuitement). L’expert génère une licence de
conception pour les concepteurs du contrôle et une licence
d’exécution pour les utilisateurs du contrôle.
Inclure les Cochez cette case pour inclure les informations de version
informations de dans le contrôle ActiveX, comme un copyright ou une
version description de fichier. Ces informations peuvent être
visualisées dans le navigateur. Spécifiez les informations de
version en choisissant Projet|Options et en sélectionnant la
page des informations de version. Cliquez sur le bouton
Aide de cette page pour plus d’informations sur chaque
paramètre.
Remarque : les informations de version sont nécessaires pour
recenser un contrôle dans Visual Basic 4.0.
Inclure la boîte Quand cette case est cochée, une boîte A propos est intégrée
A propos dans le projet. Dans un environnement de développement,
l’utilisateur du contrôle peut afficher la boîte de dialogue A
propos. La boîte de dialogue A propos est une fiche distincte
qu’il est possible de modifier. Par défaut, cette boîte de
dialogue contient le nom du contrôle ActiveX, une image,
des informations de copyright et un bouton OK.
Attributs
de liaison Description
Bindable Indique que la propriété supporte la liaison de données. Si elle est
marquée “bindable”, la propriété notifie à son conteneur que sa
valeur a été modifiée.
Request Edit Indique que la propriété supporte la notification OnRequestEdit.
Cela permet au contrôle de demander au conteneur si sa valeur
peut être modifiée par l’utilisateur.
Display Bindable Indique que le conteneur peut montrer aux utilisateurs que cette
propriété est “bindable”.
Default Bindable Indique la propriété “bindable” qui représente le mieux l’objet. Les
propriétés qui ont cet attribut de liaison par défaut doivent avoir
aussi l’attribut bindable. On ne peut pas spécifier plus d’une
propriété de ce type dans une dispinterface.
Immediate Bindable Chacune des propriétés “bindable” d’une fiche peut bénéficier de
ce comportement. Quand ce bit est défini, toutes les modifications
sont notifiées. Les bits Bindable et Request Edit doivent être définis
pour que cet attribut prenne effet.
Par exemple, pour lier un contrôle TEdit aux données d’un contrôle ActiveX,
créez le contrôle ActiveX à partir d’un TEdit puis modifiez les indicateurs de la
propriété Text en Bindable, Display Bindable, Default Bindable et Immediate
Bindable. Après le recensement et l’importation du contrôle, il peut être utilisé
pour afficher des données.
Actualisation de l’objet
Ajoutez du code à la méthode UpdateObject pour mettre à jour la propriété
quand l’utilisateur modifie les contrôles de la page de propriétés. Vous devez
ajouter du code à la méthode UpdateObject afin de définir la nouvelle valeur des
propriétés du contrôle ActiveX.
Par exemple, le code suivant affecte la propriété EditMask d’un contrôle ActiveX
(OleObject) en utilisant la valeur du contrôle boîte de saisie (InputMask) de la
page de propriétés :
Remarque Incluez le fichier .TLB qui déclare l’interface ICoClassNameDisp.
procedure TPropertyPage1.UpdateObject;
begin
{ Actualise OleObjects à partir des contrôles }
OleObject.EditMask := InputMask.Text;
end;
6 Choisissez OK.
7 Choisissez Projet|Déploiement Web.
Cela crée la base du code de déploiement contenant le contrôle ActiveX dans
une bibliothèque ActiveX (ayant l’extension OCX). Selon les options que vous
avez spécifiées, cette base du code de déploiement peut aussi contenir un
fichier cabinet (ayant l’extension CAB) ou d’information (ayant l’extension
INF).
La bibliothèque ActiveX est placée dans le répertoire destination spécifié à
l’étape 2. Le fichier HTML porte le même nom que le projet mais avec
l’extension .HTM. Il est créé dans le répertoire HTML spécifié à l’étape 4. Le
fichier HTML contient une URL faisant référence à la bibliothèque ActiveX à
l’emplacement spécifié à l’étape 3.
Remarque Si vous voulez placer ces fichiers sur votre serveur Web, utilisez un utilitaire
externe comme ftp.
8 Appelez votre navigateur Web gérant ActiveX et visualisez la page HTML
ainsi créée.
Quand cette page HTML est visualisée dans le navigateur Web, la fiche ou le
contrôle est affiché et exécuté comme application incorporée dans le navigateur.
C’est-à-dire que la bibliothèque s’exécute dans le même processus que
l’application navigateur.
Fichier .INF
Si votre contrôle ActiveX dépend de paquets ou d’autres fichiers
supplémentaires, ces fichiers doivent être inclus quand vous déployez le contrôle
ActiveX. Quand le contrôle ActiveX est déployé avec des paquets ou des fichiers
supplémentaires, un fichier portant l’extension INF (pour INFormation) est
automatiquement créé. Ce fichier spécifie les divers fichiers nécessaires devant
être téléchargés et configurés pour que la bibliothèque ActiveX s’exécute. La
syntaxe du fichier .INF permet la désignation par URL de paquets ou de fichiers
supplémentaires devant être téléchargés.
Les options de déploiement Web sont affichées sur les pages suivantes et décrites
dans les sections ci-après :
• page Projet
• page Paquets
• page Fichiers supplémentaires
• page Encodage
Combinaisons d’options
Le tableau suivant résume le résultat de la combinaison des différentes options
de déploiement Web concernant les paquets, la compression de fichiers CAB et
la signature par encodage.
Page Projet
La page Projet permet de spécifier l’emplacement de fichiers et d’URL et de
définir d’autres options de déploiement pour le projet. Les options de la page
Projet s’appliquent aux fichiers bibliothèque ActiveX ou au fichier CAB contenant
le contrôle ActiveX et devient l’option par défaut pour les paquets et fichiers
supplémentaires déployés avec le projet.
Remarque Les emplacements spécifiés sont des chemins d’accès stricts ne contenant pas de
nom de fichier.
Outre la spécification de l’emplacement des fichiers ActiveX, la page Projet
permet de spécifier s’il faut utiliser la compression de fichier CAB, les numéros
de version, l’encodage, etc. Le tableau suivant décrit les options proposées :
Page Paquets
La page Paquets permet de spécifier comment déployer les paquets utilisés dans
le projet. Chaque paquet utilisé par le projet peut spécifier individuellement ces
paramètres. Quand vous déployez votre contrôle ActiveX, vous pouvez spécifier
des options de déploiement individuellement pour chaque fichier paquet utilisé
par le projet pour le déploiement. Chacun de ces paquets peut être encodé et
placé dans un fichier CAB. Les paquets livrés avec Delphi sont déjà encodés avec
la signature Inprise.
Options CAB
Option CAB Signification
Compresser dans un CAB Crée un fichier .CAB distinct pour le paquet. C’est la valeur
séparé par défaut.
Compresser dans le CAB Inclut le paquet dans le fichier CAB du projet.
du projet
Options de sortie
Les options de sortie permettent de spécifier si le paquet comprend des
informations de version et s’il est encodé.
Options CAB
Options de sortie
Page Encodage
La Page Encodage permet à l’utilisateur du contrôle de déterminer avec certitude
qui a écrit le contrôle et si le code n’a pas été modifié depuis la signature.
Chaque fichier déployé peut avoir une signature par encodage. L’encodage ne
modifie pas les données ; il crée une signature digitale qui est ajoutée au fichier.
Pour générer une signature digitale, une valeur hachée (appelée également résumé
du message) est tout d’abord créée en utilisant l’Algorithme cryptographique
spécifié. Cette valeur hachée est ensuite signée en utilisant la clé privée.
Pour la clé privée et les fichiers justificatifs, contactez Microsoft Corporation.
Informations requises
Pour pouvoir encoder le contrôle ActiveX, vous devez spécifier une clé privée et
un fichier de certificat justificatif. Spécifiez ces valeurs dans la zone des
informations requises de la page Encodage.
Informations facultatives
Outre les informations requises, vous pouvez spécifier des informations facultatives
permettant au client de connaître le nom de l’application et de la société.
Algorithme cryptographique
Choisissez l’un des algorithmes cryptographiques suivants. MD5, la valeur par
défaut, est le plus couramment utilisé. Vous pouvez sélectionner l’un ou l’autre
des algorithmes selon qu’ils sont gérés ou non par le navigateur.
Algorithme
cryptographique Signification
MD5 L’algorithme MD5 a été développé par la société RSA Data
Security. Il génère une valeur hachée codée sur 128 bits.
SHA 1 L’algorithme SHA a été développé par le NIST (National
Institute of Standards and Technology) et par la NSA
(National Security Agency). Il génère une valeur hachée
codée sur 160 bits.
Barre
d’outils
Pages
Barre d’état
Barre d’outils
La barre d’outils de l’éditeur de bibliothèques de types, située en haut, contient
des boutons sur lesquels vous cliquez pour ajouter de nouveaux objets à la
bibliothèque de types.
Vous pouvez ajouter les types d’objet suivants à l’aide de la barre d’outils :
Icône Signification
Une bibliothèque de types. Peut être développée pour détailler les informations de
type, y compris les objets et les interfaces.
Une CoClasse.
Une énumération.
Un alias.
Un enregistrement.
Une union.
Un module.
Une propriété.
Le menu contextuel du volet liste des objets propose les options suivantes :
Nouveau Affiche un menu contenant une liste des objets à ajouter à la bibliothèque
de types. Ce sont les mêmes objets que ceux proposés dans la barre d’outils.
Couper Supprime l’objet sélectionné et le place dans le Presse-papiers Windows.
Copier Place l’objet sélectionné dans le Presse-papiers Windows.
Coller Insère un objet depuis le Presse-papiers Windows en dessous de l’objet
sélectionné.
Supprimer Supprime l’objet sélectionné.
Visualiser erreurs Inverse la visibilité de la fenêtre d’erreur.
Barre d’outils Inverse la visibilité de la barre d’outils.
Barre d’état
Lors de la modification ou de l’enregistrement d’une bibliothèque de types, les
erreurs de syntaxe, les erreurs de traductions et les avertissements sont affichés
dans le volet Barre d’état.
Si, par exemple, vous spécifiez un type non géré par l’éditeur de bibliothèques
de types, vous obtiendrez une erreur de syntaxe. Pour une liste complète des
types gérés par l’éditeur de bibliothèques de types, voir “Types autorisés” à la
page 49-24..
Page Attributs
Tous les éléments d’une bibliothèque de types ont une page d’attributs qui
permet de définir un nom et d’autres attributs spécifiques à l’élément. Si, par
exemple, une interface est sélectionnée, vous pouvez spécifier le GUID et
l’interface parent. Si un champ est sélectionné, vous pouvez spécifier son type.
Les sections suivantes décrivent en détail les attributs de chaque sorte d’élément
d’une bibliothèque de types.
Les attributs communs à tous les éléments de la bibliothèque de types sont ceux
associés à l’aide. Il est fortement recommandé que vous utilisiez les chaînes
d’aide pour décrire les éléments de la bibliothèque de types afin de faciliter son
utilisation par des applications.
Page Texte
Tous les éléments des bibliothèques de types disposent d’une page Texte qui
affiche la syntaxe de l’élément. Cette syntaxe est au format IDL (Interface
Definition Language) ou Pascal Objet. Les modifications effectuées dans les
autres pages de l’élément sont reflétées ici. Si vous ajoutez du code directement
dans la page Texte, les modifications sont reflétées dans les autres pages de
l’éditeur de bibliothèques de types.
L’éditeur de bibliothèques de types génère des erreurs de syntaxe si vous ajoutez
des identificateurs qui ne sont pas gérés par l’éditeur ; l’éditeur ne gère
actuellement que les identificateurs associés à la gestion de bibliothèques (et pas
ceux associés à la gestion RPC ou les constructions utilisées par le compilateur
Microsoft IDL pour la génération de code C++ ou la gestion du marshalling).
Pages Indicateurs
Certains éléments d’une bibliothèque de types disposent d’indicateurs qui
permettent d’activer ou d’inhiber certains comportements. Les sections suivantes
décrivent en détail les indicateurs pour chaque sorte d’élément de la bibliothèque
de types.
Utilisez la colonne défaut pour spécifier les valeurs de paramètres par défaut.
Lorsque vous ajoutez une valeur par défaut, l’éditeur de bibliothèques de types
ajoute automatiquement les indicateurs appropriés à la bibliothèque de types.
Pour modifier un indicateur de paramètre (quand vous travaillez en IDL),
double-cliquez sur le champ modificateur afin d’afficher la boîte de dialogue des
indicateurs de paramètres. Vous pouvez sélectionner les indicateurs de paramètre
suivants :
Tableau 49.12 Indicateurs de paramètres (syntaxe IDL)
Indicateur Signification
In Paramètre d’entrée. Ce peut être un pointeur, mais la valeur qu’il désigne
n’est pas renvoyée.
Out Paramètre de sortie. Ce doit être un pointeur sur un membre qui recevra
le résultat.
RetVal Reçoit la valeur renvoyée. Les valeurs renvoyées doivent avoir l’attribut
out et être le dernier paramètre (comme l’impose l’éditeur de bibliothèques
de types). Les paramètres ayant cette valeur ne sont pas affichés dans les
navigateurs à l’intention des utilisateurs.
LCID Indique que ce paramètre est un identificateur local. Un seul paramètre
peut avoir cet attribut. Il doit avoir également l’attribut in et être de type
long. Cela permet aux membres de la VTable de recevoir un LCID au
moment de l’appel. Les paramètres ayant cette valeur ne sont pas affichés
dans les navigateurs à l’intention des utilisateurs. Par convention, LCID est
le paramètre précédant la valeur renvoyée. Interdit dans un dispinterfaces.
Optional Spécifie un paramètre optionnel. Tous les paramètres suivants doivent
également être optionnels.
Has Default Cet indicateur permet de spécifier une valeur par défaut pour un
Value paramètre optionnel typé. La valeur doit être une constante pouvant se
décrire comme un VARIANT.
Default Value Si vous activez l’indicateur A une valeur par défaut, spécifiez ici la valeur
par défaut. La valeur doit être de même type que le paramètre optionnel.
Remarque Lorsque vous travaillez dans IDL, les valeurs par défaut sont spécifiées à l’aide
d’indicateurs plutôt que dans une colonne à part. De même, les identificateurs
locaux sont spécifiés à l’aide d’un indicateur plutôt qu’en utilisant un
spécificateur de type de paramètre de TLCID.
Vous pouvez utiliser les boutons Vers le haut et Vers le bas pour modifier
l’ordre des paramètres. Cependant, l’éditeur n’autorise pas des déplacements qui
violeraient une règle du langage IDL. Ainsi, l’éditeur de bibliothèques de types
applique la règle imposant que la valeur renvoyée soit toujours le dernier
paramètre de la liste des paramètres.
Attention, lorsque vous créez une propriété pour une dispinterface, vous ne
pouvez plus spécifier le type des fonctions ou des paramètres. Les indicateurs
des méthodes et propriétés des interfaces de répartition sont les mêmes que ceux
des propriétés et méthodes des interfaces décrits dans “Méthodes d’une
interface” à la page 49-10 et dans “Propriétés d’une interface” à la page 49-11.
Il est fortement conseillé de spécifier une chaîne d’aide pour les énumérations.
Voici un exemple d’entrée d’un type énumération pour un bouton de souris qui
inclut une chaîne d’aide pour chacun des éléments de l’énumération :
mbLeft = 0 [helpstring ‘mbLeft’];
mbRight = 1 [helpstring ‘mbRight’];
mbMiddle = 3 [helpstring ‘mbMiddle’];
Les paramètres des méthodes de module se spécifient comme ceux des méthodes
d’interface, comme décrit dans “Page Paramètres des propriétés et méthodes” à
la page 49-12.
Constantes de module
Pour définir une constante de module, il faut spécifier :
• Son nom
• Sa valeur
• Son type
Une constante de module peut être numérique ou chaîne, selon son attribut. Les
entrées numériques sont généralement sous la forme d’un entier au format
décimal ou hexadécimal ; ce peut être aussi une constante caractère (comme \0).
Les entrées chaîne sont délimitées par des guillemets (““) et ne peuvent s’étendre
sur plusieurs lignes. La barre oblique inverse sert de caractère d’échappement.
Quand ce caractère est suivi d’un autre caractère (y compris une autre barre
oblique inverse), il empêche l’interprétation littérale de ce caractère. Par exemple,
pour placer une barre oblique inverse dans un texte, utilisez :
“Pathname: c:\\bin\\”
Types autorisés
Dans l’éditeur de bibliothèques de types, vous utilisez des identificateurs de
types différents, selon que vous travaillez en IDL ou en Pascal Objet. Spécifiez le
langage que vous voulez utiliser dans la boîte de dialogue Options
d’environnement.
Les types suivants sont autorisés dans une bibliothèque de types pour le
développement COM. La colonne Compatible Automation spécifie si le type peut
être utilisé par une interface dont l’indicateur Automation ou Dispinterface est
activé.
Tableau 49.23 Types autorisés
Type Compatible
Pascal Type IDL Type de variant Automation Description
Smallint short VT_I2 Oui entier signé sur 2 octets
Integer long VT_I4 Oui entier signé sur 4 octets
Single single VT_R4 Oui Réel sur 4 octets
Double double VT_R8 Oui Réel sur 8 octets
Currency CURRENCY VT_CY Oui Monétaire
TDateTime DATE VT_DATE Oui Date
WideString BSTR VT_BSTR Oui Chaîne binaire
IDispatch IDispatch VT_DISPATCH Oui Pointeur sur une interface
IDispatch
SCODE SCODE VT_ERROR Oui Code d’erreur OLE
WordBool VARIANT_BOOL VT_BOOL Oui true = –1, false = 0
OleVariant VARIANT VT_VARIANT Oui Pointeur sur un Variant OLE
IUnknown IUnknown VT_UNKNOWN Oui Pointeur sur l’interface
IUnknown
Shortint byte VT_I1 Non Entier signé sur 1 octet
Byte unsigned char VT_UI1 Oui Entier non signé sur 1 octet
Word unsigned short VT_UI2 Non* Entier non signé sur 2 octets
UINT unsigned long VT_UI4 Non* Entier non signé sur 4 octets
Int64 __int64 VT_I8 Non Réel signé sur 8 octets
Largeuint uint64 VT_UI8 Non Réel non signé sur 8 octets
SYSINT int VT_INT Non* Entier dépendant du système
(Win32=Integer)
SYSUINT unsigned int VT_UINT Non* Entier non signé dépendant
du système
HResult HRESULT VT_HRESULT Non Code d’erreur 32 bits
Pointer VT_PTR -> VT_VOID Non Pointeur non typé
SafeArray SAFEARRAY VT_SAFEARRAY Non Tableau protégé OLE
PChar LPSTR VT_LPSTR Non Pointeur sur un Char
PWideChar LPWSTR VT_LPWSTR Non Pointeur sur un WideChar
* Word, UINT, SYSINT et SYSUINT peuvent être compatibles avec l’Automation dans certaines
applications.
Remarque Pour connaître les types corrects pour le développement CORBA, voir
chapitre 28, “Ecriture d’applications CORBA.”
Remarque Byte (VT_UI1) est compatible avec l’Automation, mais il n’est pas autorisé dans
un Variant ou un OleVariant car de nombreux serveurs Automation ne gèrent
pas correctement cette valeur.
Outre ces types, toute interface ou type défini dans la bibliothèque ou dans les
bibliothèques référencées peut s’utiliser dans une définition de bibliothèque de
types.
L’éditeur de bibliothèques de types stocke les informations de type en utilisant la
syntaxe IDL (Interface Definition Language) dans le fichier (.TLB) de bibliothèque
de types générée sous forme binaire.
Si le type de paramètre est précédé d’un type Pointer, l’éditeur de bibliothèques
de types le convertit en paramètre variable. Quand la bibliothèque de types est
enregistrée, les indicateurs IDL des ElemDesc associés aux paramètres variable
sont marqués IDL_FIN ou IDL_FOUT.
Souvent, les indicateurs IDL ElemDesc ne sont pas marqués par IDL_FIN ni par
IDL_FOUT lorsque le type est précédé d’un pointeur. De même, s’il s’agit de
dispinterfaces, les indicateurs IDL ne sont généralement pas utilisés. Dans ces
situations, on peut voir à côté de l’identificateur de variable un commentaire comme
{IDL_None} ou {IDL_In}. Ces commentaires sont utilisés lors de l’enregistrement
d’une bibliothèque de types, pour marquer correctement les indicateurs IDL.
Les SafeArray
COM requiert que les tableaux soient transmis via un type de données spécial, connu
sous le nom de SafeArray. Vous pouvez créer et détruire les SafeArrays en appelant
des fonctions COM particulières, et tous les éléments d’un SafeArray doivent être
types compatibles automation-valides. Le compilateur Delphi dispose
d’informations intégrées sur les SafeArrays COM et appellera automatiquement
l’API COM pour créer, copier et détruire des SafeArrays.
Dans l’éditeur de bibliothèques de types, un SafeArray doit spécifier son type de
composant. Par exemple, dans le code suivant, le SafeArray spécifie un
composant de type entier :
procedure HighLightLines(Lines: SafeArray of Integer);
Le type de composant d’un SafeArray doit être compatible avec l’Automation.
Dans l’unité de conversion de bibliothèque de types Pascal Objet, le type de
composant n’est ni nécessaire, ni autorisé.
Remarque Le choix de la syntaxe Pascal Objet ou IDL affecte également les choix
disponibles dans la page Attributs des paramètres.
Comme c’est généralement le cas pour les applications Pascal Objet, les
identificateurs des bibliothèques de types ne distinguent pas les majuscules des
minuscules. Ils peuvent avoir jusqu’à 255 caractères et doivent commencer par
une lettre ou un caractère de soulignement (_).
Par exemple, le texte suivant est la déclaration d’une interface avec deux
méthodes et une propriété :
Interface1 = interface (IDispatch)
[uuid '{7B5687A1-F4E9-11D1-92A8-00C04F8C8FC4}', version 1.0]
function Calculate(optional seed:Integer=0): Integer;
procedure Reset;
procedure PutRange(Range: Integer) [propput, dispid $00000005]; stdcall;
function GetRange: Integer;[propget, dispid $00000005]; stdcall;
end;
La syntaxe IDL correspondante est
[uuid ‘{5FD36EEF-70E5-11D1-AA62-00C04FB16F42}’,version 1.0]
interface Interface1 :IDispatch
{
long Calculate([in, optional, defaultvalue(0) ] long seed);
void Reset(void);
[propput, id(0x00000005)] void _stdcall PutRange([in] long Value);
[propput, id(0x00000005)] void _stdcall getRange([out, retval] long *Value);
};
La boîte de dialogue Appliquer les mises à jour vous avertit d'erreurs éventuelles
et insère des commentaires TODO dans le fichier source. Par exemple, si vous
renommez un événement par erreur, vous obtenez dans votre fichier source un
avertissement du type suivant :
En raison de la présence de variables d'instance dans votre fichier d'implémentation,
Delphi n'a pas pu mettre à jour le fichier pour refléter la modification du nom de
l'interface d'événement. Bien que Delphi ait mis à jour la
bibliothèque de types, vous devez mettre à jour le fichier d'implémentation manuellement.
Un commentaire TODO précède cet avertissement dans le fichier source.
Remarque Si vous ignorez cet avertissement et le commentaire TODO, le code n’est pas
compilé.
sein de l’exécutable MTS. En s’exécutant avec l’EXE MTS, les objets MTS
bénéficient des fonctionnalités de l’environnement d’exécution MTS comme le
pooling des ressources ou le support des transactions.
L’exécutable MTS (.EXE) peut être exécuté dans le même processus que le client
de base comme le montre la figure 50.2.
Figure 50.2 Composant MTS en processus
Le composant MTS peut être installé sur un processus serveur distant au sein de
la même machine comme le montre la figure suivante. Le client de base parle à
un proxy qui effectue le marshaling de la requête du client pour le stub du
composant MTS, qui à son tour accède au composant MTS via son interface.
Figure 50.3 Un composant MTS dans un serveur hors processus
Le composant MTS peut être installé dans un processus serveur distant sur un
ordinateur séparé comme le montre la figure suivante. Exactement comme dans
tout autre processus serveur distant, le client et le serveur distant communiquent
au travers de machines utilisant DCOM.
Figure 50.4 Un composant MTS dans un processus serveur distant
Activation just-in-time
La capacité d’un objet à être désactivé et réactivé alors que des clients lui font
référence est nommée activation just-in-time. Vu du client, il existe une seule
instance de l’objet à partir du moment où le client l’a créée et jusqu’au moment
où il la libère. En réalité, il se peut que l’objet ait été désactivé et réactivé de
nombreuses fois. Les objets pouvant être ainsi désactivés, les clients peuvent
continuer de faire référence à un objet pendant un temps indéterminé sans
affecter les ressources du système. Lorsqu’un objet devient désactivé, MTS libère
toutes les ressources de l’objet, par exemple, sa connexion à la base de données.
Lorsqu’un objet COM est créé en tant qu’élément de l’environnement MTS, un
objet de contexte est également créé. Cet objet de contexte existe pendant
l’intégralité de la durée de vie de l’objet MTS correspondant, pendant un ou
plusieurs cycles de réactivation. MTS utilise l’objet de contexte pour conserver la
trace de l’objet durant la désactivation. Cet objet de contexte, accessible via
l’interface IObjectContext, coordonne les transactions. Un objet COM est créé dans
l’état désactivé et devient actif lorsqu’il reçoit la demande d’un client.
Un objet MTS est désactivé lorsqu’un des événement suivants se produit :
• L’objet demande la désactivation avec SetComplete ou SetAbort : Un objet
appelle la méthode IObjectContext SetComplete lorsqu’il a terminé son travail
avec succès et qu’il n’a pas besoin de sauver l’état interne de l’objet pour un
prochain appel du client. Un objet appelle SetAbort pour indiquer qu’il ne
peut terminer son travail avec succès et que l’état de l’objet n’a pas besoin
d’être sauvé. C’est-à-dire que l’objet reprend l’état qu’il avait avant la
transaction. Souvent, les objets sont conçus sans état, ce qui signifie que les
objets sont désactivés après le retour de toutes les méthodes.
• Une transaction est validée ou annulée : Lorsqu’une transaction sur un objet
est validée ou annulée, l’objet est désactivé. Parmi ces objets désactivés, les
seuls qui continuent à exister sont ceux à qui des clients hors transaction sont
en train de faire référence. Les prochains appels à ces objets les réactivent et
les font s’exécuter dans la prochaine transaction.
• Le dernier client libère l’objet : Bien sûr, lorsqu’un client libère l’objet, il est
désactivé et le contexte d’objet également.
Attributs transactionnels
Tout composant MTS a un attribut transactionnel enregistré dans le catalogue
MTS. Le catalogue MTS maintient les informations de configuration des
composants, paquets et rôles. Vous administrez le catalogue en utilisant
l’explorateur MTS, comme décrit dans “Administration des objets MTS avec
l’explorateur MTS” à la page 50-24.
Chaque attribut transactionnel peut être défini par une des valeurs suivantes :
Requiert une Les objets MTS doivent s’exécuter dans la portée d’une
transaction transaction. Lorsqu’un nouvel objet est créé, son contexte
hérite de la transaction du contexte du client. Si le client n’a
pas de contexte transactionnel, MTS crée automatiquement
un nouveau contexte transactionnel pour l’objet.
Requiert une Les objets MTS doivent s’exécuter dans leurs propres
nouvelle transaction transactions. Lorsqu’un nouvel objet est créé, MTS crée
automatiquement une nouvelle transaction pour cet objet,
que son client ait ou non une transaction. Un objet ne
s’exécute jamais dans la portée de la transaction de son
client. Au contraire, le système crée toujours des
transactions indépendantes pour les nouveaux objets.
Supporte les Les objets MTS peuvent s’exécuter dans la portée des
transactions transactions de leur client. Lorsqu’un nouvel objet est créé,
son contexte hérite de la transaction du contexte du client.
Cela permet à plusieurs objets d’être rassemblés dans une
même transaction. Si le client n’a pas de transaction, le
nouveau contexte est également créé sans transaction.
Ne supporte pas les Les objets MTS ne s’exécutent pas dans la portée des
transactions transactions. Lorsqu’un nouvel objet est créé, son contexte
d’objet est créé sans transaction, que son client ait ou non
une transaction. Utilisez cela pour les objets COM conçus
avant le support de MTS.
Les composants MTS peuvent être déclarés de sorte que leurs objets s’exécutent
toujours dans une transaction, quelle que soit la façon dont ces objets ont été
créés. Ainsi, les objets n’ont pas besoin d’inclure de logique spéciale pour gérer
le cas où un objet est créé par un client n’utilisant pas les transactions. Cette
caractéristique réduit également le volume des applications client. Les clients
n’ont aucun besoin d’initialiser une transaction simplement parce que le
composant qu’ils utilisent l’exige.
Avec les transactions MTS, vous pouvez implémenter la logique de gestion de
votre application dans les objets serveur. Les objets serveur peuvent imposer les
règles de sorte que le client n’ait pas besoin de s’en préoccuper. Par exemple,
dans une application médicale, un client technicien radiologue peut ajouter et
voir les radiographies d’un enregistrement médical. Il n’a pas besoin de savoir
que l’application ne permet pas aux techniciens radio d’ajouter ou de voir tout
autre type d’enregistrement. Cette logique se trouve dans les autres objets
serveur de l’application.
Dispenseurs de ressources
Un dispenseur de ressources gère l’état partagé non durable de la part des
composants de l’application dans un processus. Les dispenseurs de ressources
sont semblables aux gestionnaires de ressources comme SQL Server, mais sans
garantie de durabilité. Delphi fournit deux dispenseurs de ressources :
• Dispenseur de ressources BDE
• Gestionnaire de propriétés partagées
Lorsque vous suivez cette procédure, une nouvelle unité est ajoutée au projet en
cours contenant la définition de l’objet MTS. De plus, l’expert ajoute un projet
bibliothèque de types et ouvre la bibliothèque. Alors, vous pouvez exposer les
propriétés et les méthodes de l’interface par le biais de la bibliothèque de types.
Vous exposez l’interface comme vous exposeriez n’importe quel objet
Automation comme décrit dans “Exposition des propriétés, méthodes et
événements d’une application” à la page 47-3.
L’objet MTS implémente une interface double, qui supporte à la fois l’édition de
liens précoce (lors de la compilation), via la vtable, et l’édition de liens tardive
(lors de l’exécution), via l’interface IDispatch.
L’expert objet MTS implémente les méthodes de l’interface IObjectControl,
Activate, Deactivate et CanBePooled.
Remarque Ces modèles de threads sont semblables à ceux définis par les objets COM.
Cependant, comme l’environnement MTS fournit un support des threads plus
avantageux, la signification de chaque modèle de thread diffère. D’autre part, le
modèle libre ne s’applique pas aux objets s’exécutant dans l’environnement MTS
à cause de la façon dont MTS supporte les activités.
Activités MTS
MTS supporte les accès simultanés via les activités. Tout objet MTS appartient à
une activité ; elle est enregistrée dans le contexte de l’objet. L’association entre un
objet et une activité ne peut être modifiée. Une activité comprend l’objet MTS
créé par le client de base, ainsi que tous les objets MTS créés par cet objet et ses
descendants. Ces objets peuvent être distribués dans un ou plusieurs processus
s’exécutant sur un ou plusieurs ordinateurs.
Par exemple, une application destinée à des médecins peut posséder un objet
MTS ajoutant des mises à jour et supprimant des enregistrements dans plusieurs
bases de données médicales, chacune représentée par un objet différent. Cet objet
d’ajout peut utiliser également d’autres objets, comme un objet de réception qui
enregistre la transaction. Il en résulte plusieurs objets MTS qui sont, soit
directement, soit indirectement, sous le contrôle du client de base. Ces objets
appartiennent tous à la même activité.
MTS suit le flux d’exécution dans chaque activité, en empêchant qu’un
phénomène de parallélisme n’altère malencontreusement l’état de l’application.
Le résultat de cette fonctionnalité est l’unicité du thread logique d’exécution pour
toute une série d’objets potentiellement distribuables. Grâce à ce thread logique
unique, les applications sont nettement plus faciles à écrire.
Lorsqu’un objet MTS est créé à partir d’un contexte existant, à partir d’un objet
de contexte transactionnel ou d’un objet de contexte MTS, le nouvel objet devient
membre de la même activité. Autrement dit, le nouveau contexte hérite de
l’identificateur d’activité du contexte utilisé pour le créer.
MTS n’autorise qu’un seul thread logique d’exécution pour une même activité.
Ce comportement est semblable à celui d’un apartment COM, mais les objets
peuvent être distribués dans plusieurs processus. Lorsqu’un client de base fait
appel à une activité, toutes les autres demandes de travail dans cette activité (par
exemple, celles provenant d’un autre thread client) sont bloquées jusqu’à ce que
le thread d’exécution initial revienne vers le client.
Pour plus d’informations sur les threads en l’environnement MTS, recherchez
dans la documentation MTS la rubrique "Components and Threading".
Un objet qui obtient une référence sécurisée doit libérer la référence sécurisée
lorsqu’elle ne lui est plus nécessaire.
Pour plus de détails concernant SafeRef, voir la rubrique SafeRef de la
documentation MTS.
Callbacks
Les objets peuvent faire des callbacks aux clients et aux autres composants MTS.
Par exemple, vous pouvez avoir un objet qui crée un autre objet. L’objet qui créé
peut transmettre à l’objet créé une référence à lui-même ; l’objet créé peut ensuite
utiliser cette référence pour appeler l’objet qui l’a créé.
Si vous choisissez d’utiliser les callbacks, prenez garde aux restrictions suivantes :
• Un callback au client de base ou à un autre paquet nécessite, sur le client, une
sécurité au niveau des accès. De plus, le client doit être un serveur DCOM.
• L’introduction de coupe-feux doit bloquer les callbacks vers le client.
• Le travail effectué par le callback s’exécute dans l’environnement de l’objet qui
est appelé. Il peut faire partie de la même transaction, d’une transaction
différente, ou d’aucune transaction.
• L’objet qui crée doit appeler SafeRef et transmettre la référence renvoyée à l’objet
créé en vue de se rappeler lui-même.
except
TransactionContextEx.Abort;
raise;
end;
TransactionContextEx.Commit;
end;
Lors des tests de l’objet MTS, vous pouvez commencer par le tester hors de
l’environnement MTS, afin que votre environnement de test soit plus simple.
Lorsque vous développez un serveur MTS, vous ne pouvez pas le reconstruire
lorsqu’il est encore en mémoire. Il se peut que vous obteniez une erreur du
compilateur, du style “Impossible d’écrire dans une DLL alors que l’exécutable
est chargé”. Pour l’éviter, vous pouvez définir les propriétés du paquet dans
l’explorateur MTS pour arrêter le serveur lorsqu’il est inactif.
Pour arrêter le serveur MTS lorsqu’il est inactif,
1 Dans l’explorateur MTS, cliquez avec le bouton droit sur le paquet dans lequel
votre composant MTS est installé et choisissez Propriétés.
2 Sélectionnez l’onglet Avancé.
L’onglet Avancé détermine si le processus serveur associé à un paquet
s’exécute toujours, ou s’il s’arrête après un certain temps.
3 Changez la valeur de temporisation en 0, ce qui arrête le serveur dès qu’il n’a
plus de client à servir.
4 Cliquez sur OK pour enregistrer cette option et revenir à l’explorateur MTS.
Remarque Lors des tests hors de l’environnement MTS, vous ne pouvez pas faire de référence
directe à l’ObjectProperty de TMtsObject. Le TMtsObject implémente des méthodes,
comme SetComplete et SetAbort, dont l’appel est sécurisé lorsque le contexte de l’objet
est nil.
Voici les étapes de la création d’un objet ASP à partir d’une application
existante :
• Création d’un objet ASP pour l’application.
• Exposition des propriétés et méthodes de l’application pour l’Automation.
• Recensement de l’application comme objet ASP.
• Test et débogage de l’application.
Pour davantage d’informations sur les technologies COM, voir chapitre 44,
“Présentation des technologies COM.” Pour des informations sur la création d’un
contrôleur d’Automation, voir le chapitre 46, “Création d’un contrôleur
Automation.”
Une fois ceci fait, une nouvelle unité est ajoutée au projet en cours qui contient
la définition de l’objet ASP. De plus, l’expert ajoute un projet de bibliothèque de
types. Vous pouvez maintenant exposer les propriétés et méthodes de l’interface
via la bibliothèque de types, comme décrit dans la section “Exposition des
propriétés, méthodes et événements d’une application” à la page 47-3.
Comme tous les objets Automation, l’objet ASP implémente une interface duale
qui gère la liaison précoce (à la compilation) grâce à la VTable et la liaison
tardive (à l’exécution) via l’interface IDispatch. Pour davantage d’informations sur
les interfaces duales, voir “Interfaces duales” à la page 47-7.
Comme les serveurs hors processus sont moins fiables, il est habituel de
configurer IIS pour interdire l’utilisation d’exécutables hors processus. Dans ce
cas, vous recevez un message d’erreur de la forme suivante :
Server object error 'ASP 0196'
Cannot launch out of process component
/path/outofprocess_exe.asp, line 11
De plus, comme les composants hors processus créent souvent des processus de
serveur individuels pour chaque instance d’objet, ils sont plus lents que les
applications CGI. Ils ne supportent pas aussi bien les redéploiements que les
composants DLL qui s’exécutent en processus dans IIS ou MTS. Si les
performances et le redéploiement sont des priorités, il est conseillé de ne pas
utiliser de composants hors processus.
Cependant les sites intranet qui ont un traffic faible ou modéré peuvent utiliser
un composant hors processus sans affecter les performances globales du site.
Pour des informations générales sur les serveurs en et hors processus, voir ,
“Serveurs en processus, hors processus et distants,” on page 44-6.
Index I-1
algorithmes application, serveurs 12-11 création 14-21–14-28
cryptographiques 48-27 Application, variable 5-3, 29-7 extraction de données 21-3
alias applications fourniture de requêtes 24-20
connexions de base de annulation des mises à jour en mémoire cache
données 16-7 modifications 18-27 et 25-2
connexions distantes 17-9 base de données 12-1 multiniveaux
éditeur de bibliothèques de CGI 4-12 mise à jour des
types 49-19, 49-30 client/serveur 14-1, 17-2 enregistrements 24-24–
moteur de bases de protocoles réseau 17-8 24-27
données 16-11–16-12 COM 4-12, 44-3, 44-18 régularisation des mises à
noms de base de données COM et CORBA jour 24-26
et 13-3 combinés 28-5 protocoles réseau 17-8
sessions et 13-4 CORBA 4-13, 28-1 rafraîchissement des
spécification 17-5, 17-6 distribuées 4-10––4-13 enregistrements 24-27–24-28
suppression 16-12 threads et 8-12 simples 14-33
AliasName, propriété 17-5 graphiquesl 31-8, 36-1 applications client simples 14-2
Align, propriété 2-23, 5-4 ISAPI 4-12, 29-5, 29-6 applications client/serveur 4-10
contrôles texte 6-7 MDI 4-2 applications CORBA 28-1
volets 5-32 MIDAS Web 14-32–14-44 clients 28-13
Alignment, propriété 2-14, 2-16, MTS 4-12 déploiement 28-18–28-22
2-23, 19-3 multiniveaux 14-1 serveurs 28-5–28-12
en-têtes de colonne 26-25 multithread 8-1, 16-3, 16-17– serveurs COM et CORBA
grilles de décision 27-14 16-19 combinés 28-5
grilles de données 26-24 distribuées 8-12 vue générale 28-2
mémo, champs 26-11 NSAPI 4-12, 29-5, 29-6 applications de base de
valeurs de champ 19-15 optimisation des données 11-4, 12-1
AllowAllUp, propriété 2-18 recherches 20-6 architecture 12-7, 14-32
boutons outils 5-36 réalisation de palettes 36-5, basées sur le BDE ou
turboboutons 5-34 36-6 linéaires 13-16
AllowDelete, propriété 26-32 SDI 4-2 distribuées 4-13
AllowGrayed, propriété 2-18 serveur Web 4-11 évolution 12-8, 13-21
AllowInsert, propriété 26-32 service 4-3 fichier linéraire 13-15–13-19
synchronisation des applications distantes
alTop, constante 5-32
tables 20-27 extraction de données 21-1,
Analyser Params,
Win-CGI 4-12 21-3, 21-16, 21-19
commande 24-18
applications à niveau mises à jour en mémoire cache
années bissextiles 41-8
double 12-3, 12-8, 12-10, 13-1– et 25-1
annulation des mises à jour en opérations groupées 20-24
13-12
mémoire cache 25-9–25-10 ou applications à niveau TCP/IP 30-1
annulation des unique 13-3 applications distribuées 4-10
modifications 18-27 applications à niveau base de données 4-13
ANSI unique 12-3, 12-8, 12-10, 13-1– COM 4-12
jeu de caractères 10-2 CORBA 4-13, 28-1
13-19
chaînes standard 3-26 MTS 4-12
basées sur le BDE ou
AnsiChar 3-25 linéaires 13-16 multithread 8-12
AnsiString 3-28 fichier linéraire 13-15–13-19 applications internationales 10-1
apartment, modèle de ou applications à niveau abréviations et 10-9
thread 45-6 double 13-3 conversion des saisies
Append, méthode 18-8, 18-26 applications ADO 13-12 clavier 10-8
Insert et 18-25 applications bidirectionnelles localisation 10-12
AppendRecord, méthode 18-28 méthodes 10-7 applications linéaires 13-15–
application à niveau triple Voir propriétés 10-5 13-19
applications multiniveaux applications client mémoire 13-15
application client base de données 17-2 applications MDI 4-1
instructions SQL 15-4 comme applications serveur applications multiniveaux 12-3,
application de répartition de Web 14-32 12-8, 12-11, 14-1
sockets 14-14, 14-23 CORBA 28-2, 28-13
Index I-3
AutoSessionName, application des mises à jour en batUpdate, constante 20-21,
propriété 16-19, 29-23 mémoire cache 25-6 20-23
AutoSize, propriété 5-4, 11-10, applications Web et 29-23 BeforeApplyUpdates,
26-10 association aux sessions 16-3, événement 15-6
.AVI, fichiers 7-34 16-9, 17-4 BeforeClose, événement 18-6,
AVI 2-26 BDE et 13-5 18-27
choix 12-2 BeforeConnect,
connexion 12-4, 13-5, 17-7
B pooling 50-13
événement 14-27
BeforeDisconnect,
balises HTML transparentes création 16-3, 17-3
événement 14-27
conversion 29-20 à l’exécution 17-3
dans les applications
BeforeDispatch,
paramètres 29-19 événement 29-9, 29-12
préféfinies 14-43–14-44, 29-19 multithread 13-5
DatabaseName, propriété, BeforeGetRecords,
syntaxe 29-19 événement 14-31, 15-6
Bands, propriété 2-18, 5-37 et 13-4
décompte 16-13 BeforeUpdateRecord,
barres d’état 2-23 événement 15-10
internationalisation 10-9 dénomination 17-5, 20-2
distantes 12-3 BeginDrag, méthode 6-2
barres d’outils 2-18
enregistrement de BeginRead, méthode 8-8
ajout 5-34–5-36
ajout de volets comme 5-32– données 18-27 BeginTrans, méthode 23-12
5-34 extraction de données 18-19, BeginWrite, méthode 8-8
conception 5-31–5-39 19-21, 25-1 Beveled, propriété 2-16
définition des marges 5-34 fermeture 16-6 bibliothèque COM 44-2
désactivation des boutons 5-35 génération de réponses bibliothèques
insertion de boutons 5-33–5-34, HTML 29-23–29-26 contrôles personnalisés 31-5
5-35 importation de données 20-21 bibliothèques de types 44-10,
masquer 5-38 limitation des extractions de 44-12, 44-13–44-16, 49-1
menus contextuels 5-38 données 20-12 accès 44-15
outil de dessin par locales 12-3 ajout d’interfaces 49-32
défautl 5-34 marquage d’enregistre- ajout de méthodes 49-33
transparentes 5-36, 5-37 ments 18-15–18-16 ajout de propriétés 49-33
barres de défilement 2-15 modèles multiniveaux 14-2 attributs 49-8
fenêtres du texte 6-8–6-9 modification des avantages 44-15
barres de menus données 13-10, 18-24, 18-28 contenu 44-13, 49-2
déplacement d’éléments 5-23 nouveau tri des champs 20-11 contrôles ActiveX 48-3
propriétés d’accès 42-5–42-6 création 44-14, 49-23
barres de progression 2-23
relationnelles 12-1, 15-11, 21-1 création de contrôleurs
barres graduées 2-15
sécurité 12-4 Automation 46-2
barres multiples 2-18, 5-32 sources de données et 26-6
ajout 5-37 déploiement 49-37
suppression de tables 20-18 dérecensement 44-16
conception 5-31–5-39
tables 12-15 enregistrement 49-36
configuration 5-37 changement de nom 20-18
masquer 5-38 exportation d’un fichier
test de l’état 16-5 IDL 49-37
bascules 5-34, 5-36 test des associations 16-9 IDL et ODL 44-14
base de données, transactions 12-5, 13-7 inclusion en tant que
composants 17-3 types 12-2 ressources 45-3, 49-37
base de données temporaire, Basic Object Adaptor informations de type 49-7
composants 16-9, 17-2 (BOA) 28-2, 28-16 navigateurs 44-15
base de registre 2-37 batAppend, constante 20-21, optimisation des
bases de données 4-10, 12-2– 20-23 performances 49-11
12-7, 13-3, 17-1, 17-10, 42-1 batAppendUpdate, outils 44-16
accès aux 16-1, 16-7, 20-2, 21-4 constante 20-21, 20-23 ouverture 49-32
accès non autorisé 17-7 BatchMove, méthode 20-21 page Utilise (éditeur de
ajout de données 18-25–18-26, batCopy, constante 20-21, 20-23 types) 49-8
18-28 précaution 20-21 quand les utiliser 44-14
ajout de tables 20-19 recensement 44-16, 49-36
batDelete, constante 20-21, 20-23
alias et 17-5, 20-2 recensement des objets 44-15
Index I-5
C en-têtes de colonne 26-25
entrées incorrectes 5-19
routines
bibliothèque
.CAB, fichiers 48-20 grilles de décision 27-14 d’exécution 3-29
cabinets (définition) 48-20 caractère & 2-12 distinction minuscules/
CacheBlobs, propriété 18-35 caractères 33-2 majuscules 3-30
CachedUpdates, caractères accentués 10-10 localisation Windows 3-30
propriété 18-34, 25-3 caractères d’espacement support des caractères
exécution de requêtes sur multi-octets 3-31
cadres 5-12, 5-14–5-16
des 21-6 taille 6-9
et modèles de
caractères étendus traduction 10-2, 10-8, 10-10
composants 5-14, 5-15, 5-16
routines de bibliothèque tri 10-10
graphiques 5-16
d’exécution 3-29 tronquer 10-3
partage et distribution 5-16
variables locales 3-34
ressources 5-16 caractères larges 10-3
caractères spéciaux chaînes courtes 3-26
cadres bitmap 2-26
requêtes et 21-6 chaînes de caractères
calendriers 41-1–41-13
ajout de dates 41-5–41-10 carrés, dessin 40-9 larges 47-10
définition des propriétés et CaseInsFields, propriété 13-18 chaînes longues 3-27
événements 41-2, 41-6, 41-11 cases à cocher 2-18, 26-2 champ, objets 19-1
en lecture seule 42-3–42-4 activation 26-16 affectation de valeurs 19-23,
manipulation 41-10–41-13 orientées données 26-16 19-24
redimensionnement 41-4 affichage seulement 19-8
cassettes vidéo 7-34
sélection du jour en cours 41-9 ajout 19-1–19-5, 19-7
cbsAuto, constante 26-23
callback 14-11 dynamiques ou
CDaudio, disques 7-34 persistants 19-3, 19-4
CanBePooled 50-6 CellDrawState, fonction 27-14 événements 19-20
Cancel, méthode 18-7, 18-8, CellRect, méthode 2-24 propriétés 19-3, 19-14–19-19
18-27, 23-6, 23-30 Cells, fonction 27-14 exécution 19-16
Cancel, propriété 2-17 Cells, propriété 2-25 suppression 19-14
CancelRange, méthode 20-17 cellules de grille 2-24 champs 19-1
CancelUpdates, méthode 18-34, CellValueArray, fonction 27-14 activation 19-21
25-9 cercles, dessin 40-9 affectation de valeurs 18-28
canevas 31-7, 36-2, 36-3 CGI, programmes 4-12, 29-4, affichage des valeurs 19-21,
affichage du texte 7-25 29-5, 29-6 26-13
ajout de formes 7-11–7-12, 7-14 création 29-6 ajout aux fiches 7-27–7-28
dessin 7-4 débogage 29-31 bases de données 42-5, 42-7
dessin de lignes 7-10–7-11, chaîne, champs colonnes persistantes et 26-21
7-28–7-30 saisie de données 19-18 définition 19-9, 19-10, 19-11
gestionnaires taille 19-8 définition des limites de
d’événements 7-27 chaînes 3-25, 33-2, 33-9 données 19-25–19-26
lignes dessinées 7-5 association de graphiques 6-14 enregistrements de
changement de la largeur comparaison 18-22 message 37-6
du crayon 7-6 comptage de références 3-27, lecture seule 26-3
outils de dessin par 3-34 mise à jour des valeurs 26-3
défaut 40-5 conversions PChar 3-33 modification des valeurs 26-4
palettes 36-5–36-6 conversions sur 2 octets 10-3 nouveau tri 20-11
présentation 7-1–7-3 corruption de la mémoire 3-36 obtention 19-5, 19-6
propriétés communes, déclaration et obtention de la valeur en
méthodes 7-4 initialisation 3-32 cours 25-31
rafraîchissement de l’écran 7-2 directives de compilation 3-35 obtention des valeurs
CanModify, propriété fichiers 3-43 précédentes 25-12, 25-31
ensembles de données 18-8 jeux de caractères étendus 3-36 options mutuellement
grilles de données 26-28 mélange et conversion de exclusives 26-2
requêtes 21-18 types 3-33 partage de propriétés 19-17
tables 20-5 paramètres variables 3-35 représentation 26-9
Canvas, propriété 2-25, 31-8 position de départ 6-9 saisie des données 18-25,
Caption, propriété 2-12, 2-21, présentation des types 3-26 18-26, 19-18, 26-12–26-16,
2-23 renvoi 33-9 26-17
Index I-7
code 35-4 identificateurs de composants 2-7, 32-1, 33-3
optimisation 7-15 répartition 47-8 abstraits 31-3
Code Insight implémentation 44-6 aide à la décision 27-1
modèles 4-3 informations de type 44-13 aide en ligne 38-4
code source interfaces doubles 47-7 ajout à l’unité existante 31-11
gestionnaire d’événement 2-29 marshaling 44-8 ajout à la palette des
codes caractères sur deux objets Automation 47-7-47-9 composants 38-1
optimisation 44-15 ajout aux unités 31-11
octets 10-2
pointeur d’interface 44-5 classes dérivées 31-12, 40-2
cohérence présentation 44-1
transactions 50-8 contrôles 2-6
proxy 44-7 création 31-2, 31-8
ColCount, propriété 26-32 spécification 44-2
colonnes 2-24, 26-19 dépendances 31-5–31-6
technologies 44-10 double-clic 38-13, 38-15–38-16
accès aux 19-2 threads et 8-13
affectation de valeurs 26-21, gestion mémoir et 2-10
types de serveurs 44-5 initialisation 33-12, 40-7, 42-6
26-23 COM, objets
état par défaut 26-19, 26-25 installation 2-43, 9-6–9-7, 38-21
gestion de la durée de vie 3-18 interfaces 32-4, 32-6, 43-2
grilles de décision 27-13
COMCTL32.DLL 5-32 conception 32-7
inclusion dans les tables
CommandCount, exécution 32-6
HTML 29-25
modification de valeurs 26-28
propriété 23-10 menus contextuels 38-13,
persistantes 26-18, 26-20–26-21 commandes ADO 13-15 38-14–38-15
ajout de boutons aux 26-24 annuler 23-30 modification 39-1–39-4
création 26-22–26-25 ensembles de résultats 23-30 modifier les données 42-8–
insertion 26-21 exécuter 23-30 42-13
modification de paramètres 23-19, 23-31 MTS 50-2
l’ordre 26-23, 26-29 commandes utilisateur 5-39, non visuels 31-5, 43-3
suppression 26-20, 26-21, 5-41 orientés données 42-1
26-23 Commands, propriété 23-10 palette des bitmaps 38-4
propriétés 26-19, 26-20, 26-24 CommandText, propriété 23-20, paquets 38-21
réinitialisation 26-25 23-21, 23-29, 24-20 personnalisation 2-43, 5-12,
Color, propriété 2-12, 2-25 CommandTimeout, 31-3, 33-1
crayons 7-5, 7-6 propriété 23-7, 23-30 présentation 2-10, 31-1
en-têtes de colonne 26-25 CommandType, propriétaire 2-10
grilles de décision 27-14 propriété 23-21, 23-29 propriétés communes 2-11–
grilles de données 26-24 Commit, méthode 13-7 2-13
pinceaux 7-8 CommitTrans, méthode 23-12 recensement 31-12, 38-2
Cols, propriété 2-25 renommer 2-5–2-6
CommitUpdates,
Columns, propriété 2-19, 2-21, répondre aux événements 42-7
méthode 18-34, 25-7
26-22 ressources, libération 43-5
communication entre scruter les données 42-2–42-7
grilles 26-19 niveaux 14-5, 14-9–14-12,
ColWidths, propriété 2-24, 6-16 standard 2-11
14-22 test 31-13, 43-6–43-7
COM 44-2 CORBA 14-12, 14-25
applications 44-18 composants ADO 23-1–23-31
DCOM 14-10, 14-23 composants commande 23-28
composantes 44-3 HTTP 14-11, 14-24
distribuées 4-12 composants connexion 23-3
OLE 14-25 composants ensemble de
clients 44-3, 44-9 OLEnterprise 14-12
CORBA et 28-1 données 23-12, 23-20
TCP/IP 14-10, 14-23 composants procédure
experts 44-18, 44-19, 45-1, 45-2 communications 30-1
extensions 44-2, 44-9 stockée 23-24
normes composants requête 23-22
comparaison des OMG 28-1
technologies 44-10 composants table 23-21
protocoles 29-1, 30-2 contrôles orientés
interfaces 44-3 connexion,
ajout aux bibliothèques de données 23-14
composants 12-12, 14-5
types 49-32 description 23-2
réseaux 17-8
décompte de références 44-5 ensembles
UDP et TCP 28-3
définition 44-3 d’enregistrements 23-15
standards 29-1
dérivation 44-4 présentation 23-1
composant enveloppe 43-2
Index I-9
importation 15-12 expert 48-2, 48-4 destruction 42-6
personnalisées 24-23 fichiers associés 48-25 édition 18-8, 18-24, 26-3
contraintes de données Voir gestion d’événements 48-9, grilles 12-14
contraintes 48-11 insertion
contrôle éditeur 6-7 informations de type 49-2 d’enregistrements 18-26
ContrôleBD, page de la palette informations de version 48-23 liste des 26-2
des composants 2-11, 12-13, licence 48-5, 48-8 pour modifier les
26-2 méthodes 48-9, 48-11 données 42-8–42-13
contrôles 2-7 options 48-5 pour scruter les données 42-2–
changement 31-3 orientés données 48-9 42-7
dessin 40-7, 40-9, 41-4 pages de propriétés 48-13, réponse aux changements 42-7
dessinés par le 48-14, 48-17 représentation des
propriétaire 6-13, 6-15 propriétés 48-3, 48-9, 48-10 champs 12-14, 26-9
boîtes à options 2-20 liaison 48-12 saisie de données 19-18, 26-12,
boîtes liste 2-19 publication 48-17 26-16-26-17
dessin 6-15, 6-17 recensement 45-6, 48-18 contrôles pages 2-22
dimensionnement 6-15 test 45-7, 48-19 contrôles personnalisés
événements 6-15 contrôles ActiveX,propriétés bibliothèques 31-5
styles 6-14 persistantes 48-15 contrôles préexistants 31-5
fenêtrés 31-4 contrôles animation 2-26, 7-30– contrôles texte 2-14
forme 40-7 7-32 contrôles de saisie 2-13
génération de contrôles exemple 7-31 contrôles texte formaté 2-13
ActiveX 48-3 contrôles d’édition 26-2, 26-10 contrôleurs Automation 44-10,
graphiques 31-4, 36-4, formats d’édition de texte 44-11, 46-1, 47-8
40-1-40-10 formaté 26-11 accès aux propriétés et
comparés aux bitmaps multiligne 26-10 méthodes 47-7
vs. 40-3 sélection de texte 6-9, 6-10 clients COM 44-9
création 31-4, 40-3 contrôles d’édition de texte connexion à un serveur 46-3
dessin 40-3–40-10 formaté 26-11 création à partir de
enregistrement des contrôles de saisie 2-13–2-14, bibliothèques de types 46-2
ressources système 31-4 2-15 exemple 46-5
événements 36-7 IDispatch, interface 47-8
contrôles de texte
options d’affichage 2-12 utilisation d’une interface de
multiligne 26-10, 26-11
palettes et 36-5–36-6 répartition 46-4
parcourir 2-12
contrôles éditeur de texte
formaté 2-14, 6-7 utilisation d’une interface
personnalisés 31-4 double 46-4
position 2-12 propriétés 2-14
contrôles en-têtes 2-22 controlling Unknown 3-24
pour modifier les
contrôles flèches haut-bas 2-16 ControlType, propriété 27-10,
données 42-8–42-13
pour scruter les contrôles liste 2-19–2-21 27-17
données 42-2-42-7 contrôles masque de saisie 2-13 conventions d’appel
réception de la contrôles mémo 2-13, 6-7 données membres 34-3
focalisation 31-4 propriétés 2-14 événements 34-9
redimensionnement 36-7, 41-4 contrôles onglets 2-22 méthodes 35-2
taille 2-12 contrôles orientés propriétés 33-7
données 12-13, 19-21, 26-1, types d’enregistrement de
contrôles ActiveX 44-10, 44-12,
42-1 message 37-6
44-19, 44-20
à partir de contrôles VCL 48-3 affichage des conversions 19-20, 19-22, 20-26
données 21-17, 26-5–26-6 chaîne 3-33
à partir de fiches VCL 48-7
dans les grilles 26-18, 26-20, PChar 3-33
applications Web 44-13
bibliothèques de types 44-14, 26-24, 26-31 coordonnées
48-3, 49-37 ensembles de données position de dessin
compression de fichiers multiples 26-35 actuelle 7-26
CAB 48-23 valeurs en cours 26-10 copie
création 48-1, 48-4–48-18 affichage des graphiques 26-12 ensembles de données 20-24
dates de validité 48-26 ajout 26-1–26-2 Copier, référentiel d’objets 2-42
déploiement Web 48-19 création 42-2–42-13 CopyFile, fonction 3-40
éléments 48-2 désactivation 18-14,26-5
Index I - 11
DBGridColumns, statiques 32-8 DeleteSQL, propriété 25-13
composant 26-19 virtuelles 32-9 DeleteTable, méthode 20-18
DBHandle, propriété 18-32 nouveaux types de Delphi
DBImage, composant 26-2, composants 32-3 cadre de travail ActiveX
26-12 propriétés 33-3, 33-4–33-7, (DAX) 44-2
DBListBox, composant 26-2, 33-8, 33-12, 40-4 DELPHI32.DRO 2-40
26-13 stockées 33-12 Delta, propriété 24-24
types définis par dénomination
DBLocale, propriété 18-32
l’utilisateur 40-3 sessions de base de
DBLookupComboBox, variables
composant 26-2, 26-14–26-16 données 29-23
exemple 2-8
DBLookupListBox, $DENYPACKAGEUNIT,
déclarations de type
composant 26-2, 26-14–26-16 directive de compilation 9-12
objets 2-8
DBMemo, composant 26-2, propriétés 40-3
déplacements
26-10 fichiers 3-44
types énumérés 7-12
DBNavigator, composant 26-2, déclencheurs 12-7 déploiement
26-32–26-35 ActiveX, contrôles 11-3
DECnet 30-1 applications de base de
DBRadioGroup, décompte de références
composant 26-2, 26-17 données 11-4
COM interfaces 44-5 applications généralistes 11-1
DBRichEdit, composant 26-11 objets COM 44-4
DBSession, propriété 18-32 DLL, fichiers 11-4
déconnexion 16-8, 17-9 fontes 11-11
DBText, composant 26-2, 26-9 default MIDAS, applications 11-6
DCOM 44-7 directive 33-11, 39-3 moteur de bases de données
applications mot réservé 33-8 Borland 11-5
InternetExpress 14-37 Default, propriété 2-17 paquet, fichiers 11-3
applications éléments d’action 29-12 Web, applications 11-7
multiniveaux 14-10 DEFAULT_ORDER 24-7
connexion au serveur
déploiement des
DefaultColWidth, applications 11-1
d’applications 14-23 propriété 2-24
distribution d’applications 4-12 déploiement Web 48-19
DefaultDrawing, encodage 48-21
MTS 50-16 propriété 26-29, 26-31
DCOMCnfg.exe 14-37 options 48-22
DefaultExpression, DEPLOY.TXT 11-5, 11-12
.DCP, fichiers 9-2, 9-14 propriété 19-25
.DCR, fichiers 38-4 déréférencement de pointeurs
DefaultHandler, méthode 37-3 d’objet 32-10
.DCU, fichiers 9-2, 9-14 DefaultRowHeight,
débogage dérivation de classes 32-3, 32-9
propriété 2-24 dès que possible,
applications serveur définition
Web 29-27–29-31 désactivation 14-7
classes 32-3 désactivation des mises à jour
contrôles ActiveX 45-7, 48-19
définition de licences, contrôles en mémoire cache 25-3
Microsoft IIS, serveur 29-27
Netscape, serveurs 29-30
ActiveX 48-6 DescFields, propriété 13-17
objets MTS 50-22 définition des licences, pour DESIGNONLY, directive de
Personal Web, serveur 29-29 Internet Explorer 48-6 compilation 9-12
DDecision Cube, page de la définitions d’index dessin d’images 36-7
palette des composants 2-11, client, ensembles de dessin des contrôles 40-7, 40-9,
données 13-17 41-4
12-15
définitions des champs 20-20 destination, ensembles de
déclarations
classes 32-10, 40-5 définitions des index 20-20 données
protégées 32-6 délai, événements 8-11 définition 20-22
publiques 32-6 DELETE, instructions 21-14, Destroy, méthode 2-10
publiées 32-7 21-15, 25-13 destructeurs 2-10, 35-3, 42-6
gestionnaires Delete, méthode 18-8, 18-27 objets ayant un propriétaire
d’événements 34-6, 41-12 listes de chaînes 2-36, 2-37 et 40-5, 40-7
gestionnaires de DeleteAlias, méthode 16-12 détachement des bases de
messages 37-5, 37-7 DeleteFile, fonction 3-37 données 16-8, 17-9
méthodes 7-16, 35-4 DeleteFontResourc, détail, ensembles de
dynamiques 32-10 fonction 11-11 données 20-27–20-30
publiques 35-3
Index I - 13
éditeur de bibliothèques de éditeur de collection de EditRangeStart, méthode 20-17
types 49-2 paquets 9-15 éléments d’action 29-8, 29-9,
ajout d’interfaces 49-32 éditeur de colonnes 29-10–29-13
ajout de CoClasses 49-34 création de colonnes activation et
ajout de méthodes 49-33 persistantes 26-22 désactivation 29-11
ajout de propriétés 49-33 définition des listes de ajout 29-9
ajout de types énumérés 49-34 choix 26-23 chaînage 29-13
alias 49-19, 49-30 modification de l’ordre des générateurs de page et 29-21
attributs d’aide 49-7 colonnes 26-23 gestionnaires
barre d’état 49-6 suppression de colonnes 26-23 d’événements 29-8
barre d’outils 49-3 éditeur de cube de par défaut 29-10, 29-12
CoClasses 49-16, 49-29 décision 27-8 précaution de
création de bibliothèques de éditeur de masque de changement 29-7
types 49-23 saisie 19-18 sélection 29-11, 29-12
éléments principaux 49-3 éditeur de pages Web 14-41– éléments de menu 5-20
enregistrements 49-20, 49-30 14-42 ajout 5-20, 5-29
erreurs 49-6 éditeur de paramètres de définis 5-17
informations de type 49-7 procédure stockée 22-4 déplacement 5-23
interfaces 49-9, 49-27 activation 22-18 emplacements 5-25
interfaces CORBA 28-6 définition des groupe 5-21
interfaces de répartition 49-14, paramètres 22-15 imbrication 5-22
49-28 visualisation des initialiser les propriétés 5-24
modules 49-22, 49-31 paramètres 22-14 lettres soulignées 5-21
ouverture de éditeur de paramètres de lignes de séparation 5-21
bibliothèques 49-32 modification 5-24
requête 21-10
page Attributs 49-6 nommer 5-19, 5-29
éditeur de paramètres
page Indicateurs 49-7 sélection 6-11
page Texte 49-7
StoredProc 22-4
suppression 5-21, 5-25
page Utilise 49-8 éditeur de requête de
éléments Web
pages d’informations de décision 27-6
propriétés 14-42–14-43
type 49-6 démarrage 27-7
Ellipse, méthode 7-4, 7-11, 36-3
Pascal Objet ou IDL 49-24, éditeur des propriétés de base
ellipses
49-25 de données 17-5
dessin 7-11, 40-9
serveurs d’applications 14-19 affichage des paramètres de
connexion 17-6
Embed , balise HTML
syntaxe 49-7, 49-24, 49-25 (<EMBED>) 29-20
types énumérés 49-18, 49-29 éditeur Fichiers index 20-10
éditeurs de composants 38-13– empilement 6-4
unions 49-21, 49-30 emplacement des répertoires
vérification de la syntaxe 49-36 38-17
déploiement ActiveX 48-22
volet liste des objets 49-5 par défautt 38-13
recensement 38-16 EmptyStr, variable 3-32
éditeur de champs 2-40, 19-5 EmptyTable, méthode 20-18
application d’attributs de éditeurs de propriétés 2-27,
33-3, 38-7 EnableCommit 50-10
champ 19-17
attributs 38-11 EnableConstraints,
création de champs
persistants 19-6 boîtes de dialogue méthode 24-23
définition d’ensembles comme 38-10 EnableControls, méthode 26-5
d’attributs 19-17 comme classes dérivées 38-8 Enabled, propriété
modification de l’ordre des recensement 38-12–38-13 contrôles orientés
colonnes 26-29 EditFormat, propriété 19-3, données 26-4, 26-6
suppression d’ensembles 19-15, 19-19, 26-29 éléments d’action 29-11
d’attributs 19-18 édition de données 18-8 menus 5-29, 6-11
suppression d’objets édition de propriétés sources de données 26-7
champ 19-14 champ, objets 19-15 turboboutons 5-34
éditeur de code EditKey, méthode 20-6, 20-9 encapsulation 2-2
affichage 38-16 EditMask, propriété 19-15, encodage 48-21
gestionnaire d’événement 2-29 19-18 EndRead, méthode 8-8
ouverture des paquets 9-9 EditRangeEnd, méthode 20-17, EndWrite, méthode 8-8
20-18 enregistrement
graphiques 36-4
Index I - 15
requête de données 24-20 et commercial (&), événements, renommer par
spécification des caractère 5-21 erreur 49-33, 49-36
fournisseurs 24-17 événement, objets 8-10 évolutivité 12-8, 13-21
suppression d’index 24-8 événements 2-28, 26-6, 31-7, EWriteError 3-43
synthèse des données 24-11– 34-1–34-10 Exception 3-14
24-14 accès 34-6 exceptions 3-1–3-15, 35-2, 37-3,
ensembles de données de aide sur 38-4 43-5
décision 27-6 associer au classes 3-10
ensembles de données IB 12-17 gestionnairegestionnaires composant 3-12
ensembles de données multiples d’événements déclenchement 3-15
mise à jour 25-6 partagés 2-29 définies par l’utilisateur 3-14
ensembles de données attente d’ 8-10 ensembles de données 25-30
personnalisés 12-18 champ, objets 19-20 gestion 3-2
ensembles de résultat contrôles ActiveX 46-3, 46-6, imbriquées 3-3
lecture seule 25-25 48-9, 48-11 instances 3-9
mise à jour 21-19, 25-25 contrôles graphiques 36-7 redéclenchement 3-11
ensembles de résultats 21-14, courtiers XML 14-39 réponse aux 3-2
21-17–21-19 cubes de décision 27-8 RTL 3-6
curseurs et 21-17 définition de nouveaux 34-7– silencieuses 3-13
édition 21-18 34-10 exceptions, déclenchement dans
mise à jour 21-19 délai 8-11 les interfaces COM 49-10
obtention à l’exécution 21-14 ensembles de données 18-29 Exclusive, propriété 20-5
ensembles de résultats et objets 2-9 ExecProc, méthode 22-6, 23-25,
modifiables 21-18, 21-18–21-19 exposition à l’Automation 47-4 23-26
mise à jour 25-25 gestion des messages et 37-6 ExecSQL, méthode 21-14, 21-15
restrictions 21-18, 21-19 grilles de décision 27-14 objets mise à jour 25-23
en-têtes grilles de données 26-30 Execute, méthode 2-26, 8-4,
HTTP, requêtes 29-3 hérités 34-5
23-30, 43-5
en-têtes de colonne 26-20, 26-25 implémentation 34-2
TBatchMove 20-26
en-têtes de message niveau application 5-3
threads 30-13
nommer 34-9
(HTTP) 29-1, 29-3 ExecuteTarget, méthode 5-44
objets ASP 51-3
en-têtes de réponse 29-17 exécution de procédures
objets mise à jour 25-26–25-27
en-têtes de requête 29-14 objets MTS 50-17 stockées 22-5
enveloppes 31-5, 43-2 par défaut 2-28 exécution de requêtes 21-13–
initialisation 43-3 partagés 2-30 21-15
enveloppes de composant 31-5 récupérer 34-4 à partir de fichiers texte 21-8
environnement de traduction répondre aux 42-7 objets mise à jour 25-23
intégré 10-14 signalement 8-10 exemple "techniques de
EOF, marqueur 3-44 sources de décision 27-10 dessin" 7-24–7-30
EOF, propriété 18-12, 18-13 sources de données 26-8 exemples
EPasswordInvalid 3-15 souris applications service 4-6
EReadError 3-43 glisser-déplacer 6-1 Exemples, page de la palette
erreurs test 7-27 des composants 2-11
actions groupées 20-26 événements clavier 26-6, 34-4, Expanded, propriété 26-25
fournisseurs de données 15-10 34-10 TColumn 26-25
mises à jour en mémoire internationalisation 10-8 expert composant 31-9
cache 25-28–25-31 événements de clic 34-1-34-2 experts 2-40, 8-14
précaution 25-28 événements souris 7-24–7-27, composant 31-9
override, directive et 32-9 26-6, 40-2 CORBA, objet 28-5
sockets 30-9 définis 7-24 Module de données
erreurs de compilation glisser et déplacer 6-4 CORBA 14-17–14-18, 28-5
override, directive et 32-9 informations d’état 7-25 Module de données
erreurs de mise à jour paramètres 7-25 distant 14-15–14-16
messages de réponse 14-40 test 7-27 Module de données
erésolution 15-7, 15-10 événements standard 34-7 MTS 14-16–14-17
ErrorAddr, variable 3-15 événements timer 26-6 objet COM 45-1, 45-2
Index I - 17
définition à l’exécution 18-22 lecture des propriétés 38-9, gestion d’événements 29-20,
requêtes et 18-19 38-11 29-21, 29-22
requêtes ou 21-2 nommer 35-2 générateurs de page 29-19–29-23
finally, mot réservé 36-7, 43-5 propriétés de lecture 33-7 chaînage 29-21
FindClose, procédure 3-37 Windows API 36-1 conversion de modèles 29-20
FindDatabase, méthode 16-9 Font, propriété 2-12, 7-4, 36-3 gestion d’événements 29-20,
FindFirst, fonction 3-37 en-têtes de colonne 26-25 29-21, 29-22
FindFirst, méthode 18-23 grilles de données 26-25 orientés données 29-24
FindKey, méthode 18-9, 20-6, mémon champs 26-11 générateurs de page ensemble
20-8 fontes 11-11 de données 29-24
EditKey ou 20-9 hauteur de 7-5 conversion de valeurs de
précaution d’utilisation 20-6 Footer, propriété 29-26 champ 29-24
FindLast, méthode 18-23 FOREIGN KEY, générateurs de table 29-24–
FindNearest, méthode 18-9, contrainte 15-12 29-26
20-6, 20-8 Format, propriété 27-14 définition de propriétés 29-25
précaution d’utilisation 20-6 formatage des données 19-17 générer le code de support
FindNext, fonction 3-37 applications d’événement 47-3
FindNext, méthode 18-23 internationales 10-9 gestion de la mémoire
FindPrior, méthode 18-23 formats personnalisés 19-20 interfaces 3-24
FindResourceHInstance, FormatCurr, fonction 19-19 objets COM 3-18
fonction 10-12 FormatDateTime, fonction 19-19 gestion des exceptions 3-1–3-15
FindSession, méthode 16-18 FormatFloat, fonction 19-19 blocs de protection de
First Impression 11-3 formats de données ressources 3-5
First, méthode 18-11 affectation 19-17 création d’un gestionnaire 3-7
FixedColor, propriété 2-24 personnalisation 19-20 déclaration de l’objet 3-14
formats monétaires 10-9 exécution du code de
FixedCols, propriété 2-24
formes 2-25, 7-11–7-12, 7-14 nettoyage 3-2
FixedOrder, propriété 2-19, 5-37
dessin 7-11, 7-14 flux de contrôle 3-3
FixedRows, propriété 2-24 gestionnaires par défaut 3-10
FixedSize, propriété 2-19 pourtour 7-5
remplissage 7-8 portée 3-9
FlipChildren, méthode 10-7 présentation 3-1–3-15
remplissage avec la propriété
FloodFill, méthode 7-4, 36-3 protection des allocations de
bitmap 7-9
flux 2-38 ressources 3-4
formes géométriques,
flux de fichier 3-41–3-45 protection des blocs de
dessin 40-9
création 3-41 code 3-2
E/S de fichier 3-41–3-45
Formula One 11-3
fournisseurs 14-3, 15-12 TApplication 3-13
exceptions 3-43 gestion mémoire
fin de marqueur 3-44 contraintes de données 15-11
ensembles de données client composants 2-10
mécanisme de flux de la gestionnaire de projet 5-2
VCL 3-41 et 24-16–24-28
gestion des erreurs 15-10 gestionnaire de propriétés
modification de la taille 3-44 partagées 50-13
ouverture 3-41 paquets de données 15-1
fournisseurs de données 14-19 gestionnaires d’événements 2-5,
portable 3-41
FoxPro 13-12 2-28–2-31, 19-20, 31-7, 42-7
TMemoryStream 3-41
FoxPro, tables 13-9, 20-5 affichage de l’éditeur de
flux de fichiers code 38-16
obtenir un handle 3-40 niveaux d’isolement 13-9
transactions locales 13-10 codage 2-28
flux de socket 30-13 coder 2-7
focalisation 19-21, 31-4 FrameRect, méthode 7-4
Free, méthode 2-10 contrôles dessinés par le
focalisation d’entrée 19-21 propriétaire 6-15
focalisation de saisie 31-4 FreeBookmark, méthode 18-16
déclarations 34-6, 41-12
FocusControl, méthode 19-21 définition 2-28
FocusControl, propriété 2-23 G dessin de lignes 7-27
fonctions 31-7 $G, directive de menus 2-30–2-31, 6-12
API Windows 31-4 compilation 9-12, 9-13 comme modèles 5-29
événements et 34-3 méthodes 34-3, 34-5, 34-6
GDI, applications 31-8, 36-1
graphiques 36-1 surcharge 34-6
générateurs de contenu 29-8,
paramètre Sender 2-30
29-18
Index I - 19
comportements à contexte de périphérique 7-2 générateurs de page 29-19–
l’exécution 27-21 sockets 30-6, 30-8 29-23
création 27-12 HandleException 3-13 générateurs de page ensemble
états en cours des pivots 27-10 HandleException, méthode 37-3 de données 29-24
événements 27-14 handles générateurs de table 29-24–
modification de l’ordre des connexions par socket 30-6, 29-26
colonnes/lignes 27-13 30-8 HTTP, messages de
présentation 27-12 modules ressource 10-12 réponse 29-4
propriétés 27-14 HandlesTarget, méthode 5-44 incorporation de tables 29-26
grilles de dessin 2-24 HasConstraints, propriété 19-15 modèles 29-19–29-20
grilles de données 12-14, 26-2, HasFormat, méthode 6-11, 7-23 HTML, tables 29-20, 29-26
26-31 Header, propriété 29-26 création 29-24–29-26
affichage des champs Height property définition des propriétés 29-25
ADT 26-25 TScreen 11-9 légendes 29-26
affichage des champs Height, propriété 2-12, 5-3, 26-13 HTMLDoc, propriété 14-40,
tableau 26-25 HelpContext, propriété 2-24 29-20
affichage des données 26-18, HelpFile, propriété 2-24 HTMLFile, propriété 29-20
26-20, 26-24, 26-31 héritage 2-2 HTTP 29-2
dessin 26-29 héritage de classe 2-6 applications de bases de
édition 26-28 données multiniveaux 14-11
hérite des classes 32-8
des données 26-4 code de statut 29-16
état par défaut 26-19
héritées
propriétés 40-2, 41-2 connexion au serveur
restauration 26-25 d’applications 14-24
gestion des événements 26-30 Hériter, référentiel d’objets 2-42
en-têtes de message 29-1
insertion de colonnes 26-22 heure
en-têtes de réponse 29-17
modification de l’ordre des internationalisation 10-9
en-têtes de requête 29-3, 29-14
colonnes 26-23, 26-29 saisie 2-21
et serveurs
obtention des valeurs 26-19, heure, champs 19-18 d’applications 14-15
26-20 formatage des valeurs 19-19
présentation 29-3–29-5
à l’exécution 26-21 HideSelection, propriété 2-14 HTTP, messages de réponse
options à l’exécution 26-27 hiérarchie (classes) 32-4 Voir messages de réponse
personnalisation 26-20–26-21 Hint, propriété 2-24 HTTP, messages de requête
présentation 26-18 Hints, propriété 26-35 Voir messages de requête
propriétés 26-32 HorzScrollBar 2-15 httpsrvr.dll 14-11, 14-24
saisie de données 26-23 Host, propriété
suppression de client, sockets 30-6
colonnes 26-20-26-21, 26-23 TSocketConnection 14-23 I
grilles tabulaires 26-31 HostName, propriété IAppServer, interface 14-5,
ggroupe de turboboutons 5-34 TCorbaConnection 14-25 14-8–14-9, 14-19–14-21, 14-31
Grouped, propriété hôtes 14-23, 30-4 IClassFactory, interface 44-5
boutons outils 5-36 adresses 30-4 icon
groupes de news 1-3 URL 29-2 objets graphiques 7-3
groupes de propriétés HotImages, propriété 5-35 icônes 2-25, 36-4
partagées 50-13 HotKey, propriété 2-16 barres d’outils 5-35
GroupIndex, propriété 2-17 HRESULT 47-10 vues arborescentes 2-20
menus 5-30 HTML IConnectPoint 47-3
turboboutons 5-34 applications IConnectPointContainer 47-3
GroupLayout, propriété 27-11 InternetExpress 14-35 ID référentiel 28-12
Groups, propriété 27-11 modèles par défaut 14-40, IDataIntercept, interface 14-24
GUID 3-20, 44-4 14-43 identificateurs
génération 3-20 HTML, commandes 29-19 données membres de
génération 29-20 classe 34-3
H informations de base de événements 34-9
données 29-24 incorrects 5-19
$H, directive de HTML, documents 29-3 interfaces de répartition 47-8
compilation 3-27, 3-35 bases de données et 29-23 liaison à 47-9
Handle, propriété 3-42, 31-4, ensembles de données 29-26 méthodes 35-2
31-5, 36-3
Index I - 21
modules de données destruction d’objets 3-22 optimisation 44-15
distants 14-16 DLL 28-15 paramètres 47-10
objets COM 45-2, 45-3 éditeur de bibliothèques de interfaces du composant
objets CORBA 28-5 types 49-9, 49-27 propriétés, déclaration 43-3
instructions d’affectation 33-2 éléments de programme non interfaces utilisateur
instructions SQL visuels 31-5 disposition 5-3–5-4
ADO 23-28 exécution 32-6 fiches 5-1
ensembles de données de extension du modèle InternalCalc, champs 19-8,
décision et 27-6 d’héritage simple 3-15, 3-16 24-10
fournies au client 24-20 gestion de la durée de internationales
IntegralHeight, propriété 2-19, vie 3-18, 3-22 applications 10-1
26-13 gestion de la mémoire 3-19, internationalisation 10-1
intégrité 3-22 Internet Engineering Task
violations 20-26 IID 3-20, 3-24 Force 29-1
intégrité des données 15-11 implémentation 28-7, 44-6 Internet Information Server
intégrité référentielle 12-7 internationalisation 10-8, 10-10, (IIS) 51-1
InterBase, pilote 10-13
Internet, page de la palette des
déploiement 11-6 interrogation dynamique 3-18
composants 2-11
InterBase, tables 21-4 IUknown,
implémentation 3-18
Internet, standards et
interface d’appel dynamique protocoles 29-1
liaison anticipée 14-28
Voir DII InternetExpress 14-32, 14-34–
liaison différée 28-4
interface de document 14-44
liaison tardive 14-28
multiple 4-1 liaisons dynamiques 3-19 InternetExpress, page palette de
interface de document marshaling 3-25 composants 14-35
unique 4-1 modules de données intervalles de
Interface Definition Language distants 14-19–14-21 rafraîchissement 26-5
(IDL) 28-6, 49-1 nom 28-5 intranets
Interface Description Language objets externes 3-21 noms d’hôte 30-4
(IDL) 44-16 objets internes 3-22 Voir aussi réseaux locaux
interface du composant opérateur as 3-19 InTransaction, propriété 13-7,
création 43-3 optimisation du code 3-23 23-12
interface, mot réservé 3-15 partage entre les classes 3-16 Invalidate, méthode 40-9
interfaces 3-15–3-25, 32-4, 32-6, polymorphisme 3-16 Invoke, méthode 47-8
43-2, 43-3 présentation 3-15–3-25 IObjectContext 50-7
agrégation 3-20, 3-21 procédures 3-17 IP, adresses 30-4, 30-6
appel dynamique 3-25 propriétés, déclaration 43-3 hôtes 30-4
applications distribuées 3-24 recensement 28-9 noms d’hôte 30-4
applications réutilisation du code 3-20 IPaint, interface 3-17
multiniveaux 14-8–14-9 squelettes et 28-3 IPersist, interface 3-16
appel 14-27 stubs et 28-2, 28-3 IProvideClassInfo, interface
Automation 47-7–47-9 TComponent 3-24 bibliothèques de types 44-14
bibliothèques de types et 44-12 utilisation 3-15–3-25 IProvider, interface
caractéristiques du interfaces COM, déclenchement création 12-12
langage 3-15 des exceptions 49-10 IProviderSupport, interface 15-2
CLSID 3-24 interfaces de répartition 47-8 IPX/SPX, protocoles 30-1
code exemple 3-16, 3-21, 3-23 attributs (éditeur de irep 28-9
COM 3-24, 44-1, 44-3, 45-3 bibliothèques de types) 49-14
composants 3-24
IRotate, interface 3-17
compatibilité des types 47-9 is, mot réservé 2-9
comptage de références 3-18, éditeur de bibliothèques de
3-19, 3-22–3-24 ISAPI 11-7
types 49-28
conception 32-7 ISAPI, applications 4-12, 29-5
identificateurs 47-8
CORBA 3-24, 28-3, 28-6–28-9 création 29-6
interfaces de types 44-15 débogage 29-27
types autorisés 28-7 interfaces doubles
Ctrl+Shift+G 3-20 messages de requête 29-7
compatibilité des types 47-9 IsCallerInRole, méthode 14-6
de répartition 47-8 marshaling automatique 44-18
délégation 3-20 isolation
MTS 50-17
dérivation 3-18 transactions 50-8
Index I - 23
listes de champs -LUpackage, directive de mémoire dynamique 2-38
persistants 19-5 compilation 9-13 mémoires caches internes 25-1
affichage 19-6, 19-7 mémos 33-9
listes de choix 26-23 M menu items
listes de fichiers setting properties 5-25
déplacement des éléments 6-3 MainMenu, composant 5-17 Menu, propriété 5-30
faire glisser des maître/détail, fiches 12-14 menus 5-16–5-29
éléments 6-2, 6-3 maître/détail, relations 12-14 accès aux commandes 5-21
listes de recherche (système client, ensembles de affichage 5-24, 5-25
d’aide) 38-5 données 14-30 ajout 5-19–5-24
listes déroulantes 26-21 tables imbriquées 14-30 d’autres applications 5-31
affectation de valeurs 26-23 Mappings, propriété 20-25 d’images 5-23
ListField, propriété 26-16 Margin, propriété 2-17 déroulants 5-22–5-23
listres de chaînes marquage des déplacement parmi 5-26
dessinées par le enregistrements 18-15–18-16 enregistrer comme
propriétaire 6-14 marshaling 44-7 modèles 5-27, 5-28–5-29
ListSource, propriété 26-16 dans les interfaces gestion des événements 2-30–
-LNpath, directive de CORBA 28-3 2-31, 5-29
compilation 9-13 documents Active 44-17 internationalisation 10-9, 10-10
Loaded, méthode 33-12 documents OLE 44-17 modèles 5-19, 5-25, 5-27–5-29
données COM 47-9 chargement 5-27
LoadFromFile, méthode 21-8,
IDispatch, interface 44-12 suppression 5-28
23-18, 36-4 nommer 5-19
client, ensembles de interfaces COM 44-8
interfaces doubles 44-18 réutilisation 5-25
données 13-19
personnalisé 28-14 surgissants 6-12
ensembles de données
squelettes 28-8 menus contextuels
client 24-30
masques ajout d’éléments 38-14, 38-15
graphiques 7-20
édition de données 19-18 barres d’outils 5-38
listes de chaînes 2-32
MasterFields, propriété 20-27 concepteur de menus 5-25
LoadFromStream, méthode
MasterSource, propriété 20-27 menus déroulants 5-22–5-23
ensembles de données
Max, propriété 2-15 affichage 5-24
client 24-30
Max, propriété 2-24 menus déroulants et 5-22
localaddr, fichier 28-22
MaxDimensions, menus surgissants 6-12–6-13
locales 10-1
propriété 27-22 messages 5-4, 37-1–37-8, 41-4
formats des données et 10-9
MaxLength, propriété 2-14 clavier 42-9
modules ressource 10-10
contrôles d’édition de texte décomposeur 37-2
localisation 10-1, 10-13 définis 37-2
présentation 10-1 formaté 26-11
mémo, champs 26-10 par l’utilisateur 37-5, 37-7
localisation des enregistrements
ressources 10-10, 10-12-10-13 MaxRecords, propriété 14-38
types, déclaration 37-6
Locate, méthode 18-9, 18-17 MaxRows, propriété 29-25
gestion 37-5
Lock, méthode 8-7 MaxSummaries, propriété 27-22 gestionnaires 37-1, 37-3, 41-4
LockList, méthode 8-7 MaxValue, propriété 19-15 création 37-5–37-8
LoginPrompt, propriété 17-7, MBCS 3-30 déclarations 37-5, 37-7
23-8 MDI, applications par défaut 37-3
longues création 4-2 surcharge 37-4
chaînes 3-27 menus identificateurs 37-6
Lookup, méthode 18-9, 18-18 fusion 5-30–5-31 souris 42-9
LookupCache, propriété 19-12 mémo, champs 26-2, 26-10 messages d’erreur 25-30
LookupDataSet, texte formaté 26-11 internationalisation 10-10
propriété 19-12, 19-15 mémoire messages de la souris 42-9
LookupKeyFields, composants d’aide à la messages de réponse 29-8
décision 27-21 contenu 29-17, 29-18–29-26
propriété 19-12, 19-15
conservation 32-10 création 29-16–29-18, 29-18–
LookupResultField,
infiltrations dans les fiches 5-5 29-26
propriété 19-15 libération de bitmap 7-22
lParam, paramètre 37-2 envoi 29-13, 29-18
mémoire cache
LPK_TOOL.EXE 48-6 ressources 36-2
Index I - 25
modèles de threads regroupement 14-8 MouseDown, méthode 42-9
contrôles ActiveX 48-5 sans état 14-7, 14-8, 14-30– MouseToCell, méthode 2-24
MTS 50-17 14-32 .MOV, fichiers 7-34
objets COM 45-2, 45-4 modules de données MTS Move, méthode
objets CORBA 28-6 attributs de transaction 14-17 listes de chaînes 2-36, 2-37
modèles HTML 14-43–14-44 expert 14-16-14-17 MoveBy, méthode 18-12
modèles threading 8-14 interface 14-20 MoveCount, propriété 20-26
modules de données modèles threading 14-17 MoveFile, fonction 3-40
CORBA 14-18 modules ressource 10-10, 10-12 MovePt 7-29
modules de données mois, renvoyer actuel 41-8 MoveTo, méthode 7-4, 7-8, 36-3
distants 14-15 monnaie .MPG, fichiers 7-34
modules de données internationalisation 10-9 MTS 4-12, 44-2, 44-9, 50-1
MTS 14-17 Month, propriété 41-5 activités 50-18
modèles, programmation 4-3 MonthCalendar, administration des objets 50-24
modes de configuration composant 2-21 applications de base de
sessions de base de moteur de bases de données données multiniveaux 14-6–
données 16-11 Borland 4-10, 12-2, 16-1, 18-32 14-8
modes de dessin 7-30 actions groupées 20-24, 20-25 callbacks 50-21
modification alias 16-11–16-12 clients de base 50-2, 50-15
d’enregistrements 20-24 connexions distantes 17-9 composants 50-2
données spécification 17-5, 17-6 connexion aux bases de
transactions et 13-10 API, appels 13-2 données 14-8
Modification de graphe, boîte appels directs 18-33 contextes d’objet 50-7
de dialogue 27-19 applications à niveau unique débogage d’applications
modification des propriétés et à niveau double 13-2– serveur Web 29-28–29-29
tableau 33-3 13-12 exigences 50-4
modifications, annulation 18-27 applications linéaires et 13-15 libération des ressources 50-6
Modified, méthode 42-12 applications Web et 11-7 paquets 50-14
Modified, propriété 2-14 connexion aux bases de pooling des connexions aux
Modifiers, propriété 2-16 données 13-5 bases de données 50-6
ModifyAlias, méthode 16-12 déploiement 11-4, 11-5, 11-12 pooling des objets 50-6
ModifySQL, propriété 25-13 détermination des types de proxy 14-21
modules 31-11 table 20-3 références aux objets 50-20
éditeur de bibliothèques de ensembles de données client regroupement des connexions
types 49-22, 49-31 et 12-18 de base de données 14-6
modules de données 2-38–2-40 extraction de données 18-31, sécurité 50-12,
applications Web et 29-7, 29-9 21-3, 21-15, 21-18 transactions 50-5, 50-7, 50-12
bases de données 17-11 fermeture des connexions de attributs 50-8
composants session et 16-19 base de données 16-8, 16-9 contrôlées par le client 50-10
créer 2-38 mise à jour des données 25-25, temporisations 50-11
distant ou standard 2-38 25-28 multimédia 7-35
distants Voir modules de noms de pilote 17-5 multiniveaux
données distants ouverture des connexions de architecture basée sur le
modifier 2-38 base de données 16-7 Web 14-32
règles de gestion 2-39 répertoires privés 16-15 architecture des
requêtes multitables 21-16 applications 14-4
modules de données CORBA
expert 14-17-14-18, 28-5 serveurs distants et 17-8, 17-9 Multi-niveaux, page (Nouveaux
instanciation 14-18 test des associations 16-9 éléments, boîte de
modèles threading 14-18 moteurs de bases de données, dialogue) 14-3
modules de données autres 11-5 MultiSelect, propriété 2-19
distants 14-3, 14-5, 14-13, motifs 7-9 multithread, applications 8-1
14-15–14-18 motifs de remplissage 7-8 multitraitement
expert 14-15-14-16 mots clés 38-5 threads 8-1
instanciation 14-16 protected 34-6 mutuellement exclusifs,
interfaces 14-19–14-21 mots de passe 17-2 options 5-34
modèles threading 14-15, 14-17 Paradox, tables 16-15
sessions et 13-4
Index I - 27
objets requête OnClientDisconnect, OnGetData, événement 15-6
informations d’en-tête 29-8 événement 30-8 OnGetDataSetProperties,
objets temporaires 36-7 OnClientRead, événement événement 15-5
objets thread serveur,sockets 30-11 OnGetSocket, événement
initialisation 8-3 OnClientWrite, événement serveur, sockets 30-10
objets utilitaires 2-31 serveur,sockets 30-11 OnGetTableName,
objets visuels OnColEnter, événement 26-30 événement 15-11
inter-processus 44-10 OnColExit, événement 26-30 OnGetText, événement 19-19,
.OCX, fichiers 11-3 OnColumnMoved, 19-20
ODBC 23-2 événement 26-29, 26-30, 26-31 OnGetThread, événement 30-10
ODBC, pilotes 17-8, 17-9 OnCommitTransComplete, onglets
ADO 13-13 événement 23-12 draw-item, événements 6-17
niveaux d’isolement 13-9 OnConnect, événement styles dessinés par le
utilisant ADO 13-13 client, sockets 30-9 propriétaire 6-14
ODL (Object Description OnConnectComplete, OnHTMLTag, événement 14-44,
Language) 44-14, 44-16, 49-1 événement 23-5 29-20, 29-21, 29-22
OEM, jeux de caractères 10-2 OnConnecting, événement OnKeyDown, événement 26-31,
OEMConvert, propriété 2-14 client, sockets 30-9 34-5, 42-10
OldValue, propriété 25-12, OnConstrainedResize, OnKeyPress, événement 26-31,
25-31 événement 5-4 34-5
OLE OnCreate, événement 31-13 OnKeyUp, événement 26-31,
applications OnDataChange, 34-5
fusion de menus 5-30 événement 26-8, 42-7, 42-11 OnLayoutChange,
connexion aux serveurs OnDataRequest, événement 27-10
d’applications 14-25 événement 15-11, 24-28 OnListen, événement
OLE 32.dll 44-2 OnDblClick, événement 26-30, serveur, sockets 30-10
OLE DB 13-13, 23-2 34-5 OnLogin, événement 17-3, 17-7,
OLEAut32.dll 44-2 OnDecisionDrawCell, 23-8
OLEnterprise 11-6, 14-12, 14-15 événement 27-14 OnLookup, événement
connexion aux serveurs OnDecisionExamineCell, client, sockets 30-9
d’applications 14-25 événement 27-14 OnMeasureItem,
OLEView 44-16 OnDisconnect, événement 23-5 événement 6-16
OMG 28-1 client, sockets 30-7 OnMouseDown,
OnAccept, événement OnDragDrop, événement 6-3, événement 7-25, 34-5, 42-9
serveur, sockets 30-10 26-30, 34-5 paramètres transmis à 7-25
OnAction, événement 29-13 OnDragOver, événement 6-2, OnMouseMove,
OnAfterPivot, événement 27-10 26-30, 34-5 événement 7-25, 7-26, 34-5
OnBeforePivot, OnDrawCell, événement 2-24 paramètres transmis à 7-25
événement 27-10 OnDrawColumnCell, OnMouseUp, événement 7-14,
OnBeginTransComplete, événement 26-29, 26-30 7-25, 7-26, 34-5
événement 23-12 OnDrawDataCell, paramètres transmis à 7-25
OnCalcFields, événement 18-10, événement 26-30 OnNewDimensions,
19-10 OnDrawItem, événement 6-17 événement 27-10
OnCalcFields, OnEditButtonClick, OnPaint, événement 2-25, 7-2
événements 18-30 événement 26-30 OnPassword, événement 16-16,
OnCellClick, événement 26-30 OnEndDrag, événement 6-3, 17-2
OnChange, événement 19-20, 26-30, 34-5 OnPopup, événement 6-12
36-7, 40-7, 41-12, 42-12 OnEndPage, événement 51-3 OnRead, événement
OnClick, événement 2-17, 34-1, OnEnter, événement 26-30, client, sockets 30-11
34-3, 34-5 26-34, 26-35, 34-5 OnReconcileError,
menus 2-30 OnError, événement événement 24-25, 24-26
OnClick,événement sockets 30-9 OnRefresh, événement 27-8
boutons 2-4 OnExit, événement 26-30 OnResize, événement 7-2
OnClientConnect, OnFilterRecord, OnRollbackTransComplete,
événement 30-7 événement 18-10, 18-19, 18-21 événement 23-12
serveur, sockets 30-10
Index I - 29
création 4-9, 9-8–9-13 spécification 33-11 partie publiée des classes 32-7
déploiement spécification des valeurs Pascal Objet
d’applications 9-3, 9-14 propriété par défaut 33-11 présentation 2-1
directives de compilation 9-11 Paradox, tables 16-2, 20-2, 20-3 PasswordChar, propriété 2-14
DLL 9-1, 9-2 accès aux données 20-5, 21-4 PasteFromClipboard,
édition 9-9 actions groupées 20-26, 20-27 méthode 6-10, 26-11
exécution 9-1, 9-3–9-5, 9-8 ajout d’enregistrements 18-26 graphiques 26-12
extensions de noms de création d’alias 16-12 PathInfo, propriété 29-11
fichiers 9-1 DatabaseName 13-4 pbmByName, constante 22-17
fichiers source 9-2, 9-14 droits d’accès pbmByNumber, constante 22-17
installation 9-6–9-7 insuffisants 16-16 PChar 3-28
internationalisation 10-12, extraction d’index 20-10 conversions chaîne 3-33
10-13 fichiers de contrôle
PDOXUSRS.NET 16-14
liste Contient 9-8, 9-11, 38-21 réseau 16-14
mémo, champs 26-10, 26-11
Pen, propriété 7-4, 7-5, 36-3
liste Nécessite 38-21
niveaux d’isolement 13-9 PenPos, propriété 7-4, 7-7
liste Requires 9-8, 9-10
modification 9-9 ouverture des connexions 16-7 PENWIN.DLL 9-13
options 9-9 parcours 20-6, 20-9 perforation, fiches 12-14
paramètres par défaut 9-9 protection par mot de performances, optimisation
personnalisés 9-5 passe 16-15 dans les bibliothèques de
référencement 9-4 répertoires 13-5 types 49-11
références dupliquées 9-10, requêtes 21-18 périphériques média 7-32
9-11 transactions locales 13-10 Personal Web, serveur
Seulement en conception, ParamBindMode, débogage 29-29
option 9-8 propriété 22-17 personnalisation de
utilisation 4-9 ParamByName, méthode 21-11, composants 33-1
utilisation dans des 23-19, 23-31 PickList, propriété 26-23, 26-25
applications 9-3–9-5 Parameters, propriété 23-19, picture, objets 7-3
paquets de données 14-19, 15-1 23-31 Picture, propriété 2-25, 7-18
actualiser les enregistrements paramètres dans les cadres 5-16
modifiés 15-4 applications Pie, méthode 7-4
champs 15-3 multiniveaux 24-18 pilotes de base de données 12-2
contenu 15-1 classes comme 32-10 pinceaux 7-8–7-9, 40-5
en lecture seule 15-4 DLL appels 28-15 bitmap, propriété 7-9
informations ensembles de données changement 40-7
d’application 24-14 client 24-17 couleurs 7-8
informations définies par événements souris 7-25 styles 7-8
l’application 15-5 gestionnaires pivots de décision 27-11
lecture 15-5 d’événements 34-3, 34-8, 34-9 comportement à
modification 15-6, 15-7 HTML, balises 29-19 l’exécution 27-20
propriétés des champs 15-4 interfaces doubles 47-10 propriétés 27-11
restreindre les modifications messages 37-2, 37-6 Pixel, propriété 7-4, 36-3
du client 15-4 paramètres de propriété 33-7 pixels
unicité des propriétés de tableau 33-9 lecture et définition 7-9
enregistrements 15-3 paramètres d’entrée 22-11 Pixels, propriété 7-5, 7-9
XML 14-32, 14-34, 14-38 paramètres de propriété pmCopy, constante 7-30
lecture 14-38–14-39 écriture 33-9 pmNotXor, constante 7-30
paquets delta 15-6 lecture 33-7, 33-9 pointeur de la souris
modification 15-6–15-8 paramètres de sortie 22-11 glisser-déplacer 6-4
XML 14-38, 14-39–14-40 paramètres facultatifs 24-14 pointeurs
paquets MTS 50-23 paramètres optionnels 15-5 Automation 47-8
par défaut ParamName, propriété 14-42 classe 32-10
classe ancêtre 32-4 Params, propriété 17-6, 17-7 méthode 34-3
gestionnaires courtiers XML 14-38 valeurs de propriété par
message 37-3 requêtes 21-11 défaut 33-11
valeurs 19-25, 26-12 Parent, propriété 31-14 pointeurs de méthode 34-2,
valeurs de propriété 33-8 34-3, 34-9
ParentShowHint, propriété 2-24
modification 39-2, 39-3
Index I - 31
propriétés initialisation 2-27 limitation 14-11 redimensionnement des 11-9,
propriétés privées 33-5 rapports 12-18 41-4 contrôles
protected 2-8 .RC, fichiers 5-31 graphiques 36-7
directive 34-6 Read, méthode références
événements 34-6 TFileStream 3-43 bibliothèques de types 49-8
mot clé 33-3, 34-6 read, méthode 33-7 fiches 5-2
protégée read, mot réservé 33-9, 40-4 paquets 9-4
partie des classes 32-6 ReadBuffer, méthode références circulaires 5-2
protocole (Digital) 30-1 TFileStream 3-43 références croisées 27-2–27-3,
protocoles README.TXT 11-12 27-12
choix 14-9–14-12 ReadOnly, propriété 2-14, 42-3, à plusieurs dimensions 27-3
connexion, composants 14-22 42-10 à une dimension 27-3
connexions réseau 17-8 contrôles d’édition de texte définition 27-2
Internet 29-1, 30-1 formaté 26-11 valeurs récapitulatives 27-3
ProviderFlags, propriété 15-9 contrôles orientés référentiel 5-12
ProviderName, propriété 14-21, données 19-16, 26-3 d’implémentation 28-4
14-38 grilles de données 26-25, 26-28 référentiel d’interfaces 28-4
proxy 44-7 mémo, champs 26-10 ajout d’interfaces 28-10
proxy MTS 14-21, 50-4 tables 20-5 exécution 28-9
PString 3-33 réalisation de palettes 36-5, 36-6 recensement des interfaces
public 2-8 ReasonString, propriété 29-17 CORBA 28-9, 28-9–28-10
directive 34-6 recensement suppression d’entrées 28-10
mot clé 34-6 composants 31-12 référentiel d’objets 2-40–2-43,
propriétés 33-10 contrôles ActiveX 48-18 5-12
publication éditeurs de composants 38-16 ajouter des éléments 2-41
propriétés éditeurs de propriétés 38-12– conversion d’applications
exemple 40-2, 41-2 38-13 serveur Web 29-31
publique interfaces CORBA 28-9 répertoire partagé 2-41
partie de classes 32-6 objets ASP 51-4 utiliser des éléments 2-41–2-42
published 2-8, 33-3 recherche Refresh 5-45
directive 33-3, 34-6, 43-4 d’enregistrements 18-9 Refresh, méthode 26-5
mot clé 34-6 réitération de recherches 20-9 RefreshLookupList,
propriétés 33-10, 33-11 recherche de données 18-9 propriété 19-13
PWideChar 3-28 clés partielles et 20-8 RefreshRecord, méthode 24-27
PWideString 3-33 recherches incrémentales 26-16 Register, méthode 7-3
réitération de recherches 20-9 Register, procédure 31-12, 38-2
Q recherche incrémentales 26-16
recherches indexées 18-9, 18-17,
RegisterComponents,
procédure 9-7, 31-12, 38-2
QReport, page de la palette des 18-18, 20-6 RegisterPooled, procédure 14-8
composants 2-11 RecNo, propriété RegisterPropertyEditor,
qualificateurs 2-7 ensembles de données procédure 38-12
Query, propriété client 24-2 RegisterTypeLib, fonction
objets mise à jour 25-19 RecordCount, propriété 20-26 bibliothèques de types 44-15
QueryInterface, méthode 3-18, RecordSet, propriété 23-15 registres 2-37, 10-9
3-22, 3-24 Recordset, propriété 23-31 règles d’entreprise 14-2
IUnknown 44-4 RecordSetState, propriété 23-15 règles de gestion
Rectangle, méthode 7-5, 7-11, modules de données 2-39
R 36-3 regroupement de
rectangles composants 2-22
raccourcis 2-12, 2-16 dessin 7-11, 40-9 regroupement de
ajout aux menus 5-21 rectangles à coins arrondis 7-11 contrôles 2-21–2-22
raccourcis clavier récupération d’enregistrements
ajout aux menus 5-21
regroupement des objets
en mémoire cache 25-10–25-11 modules de données
raise, mot réservé 3-15 redéclaration des distants 14-8
rappels propriétés 34-6 REGSERV32.EXE 11-3, 11-6
applications
redéfinition des méthodes 32-9
multiniveaux 14-20
Index I - 33
SafeRef 50-20 SelEnd, propriété 2-15 modules de données
sans état Self, paramètre 31-13 distants 2-40
objets 50-9 SelLength, propriété 2-14, 6-9 multiniveaux
SaveConfigFile, méthode 16-11 SelStart, propriété 2-15, 6-9 fournisseurs de
SaveToFile, méthode 7-20, SelStart, propriété données 14-19, 15-1
23-18, 36-4 2-14 threads 8-12
client, ensembles de SelText, propriété 2-14, 6-9 serveurs de bases de
données 13-19 Sender, paramètre 2-30 données 4-10, 17-7, 21-3
ensembles de données exemple 7-7 serveurs de bases de données
client 24-31 séparateurs distants Voir serveurs distants
listes de chaînes 2-32 composants 2-16 serveurs de messagerie
SaveToStream, méthode server, applications threads 8-12
ensembles de données extraction de données 21-3 Voir aussi applications serveur
client 24-31 ServerType, propriété 30-10, Web
ScaleBy, propriété 30-11, 30-12 serveurs distants 12-3, 16-7,
TCustomForm 11-9 serveur Automation 21-4, 44-7
Scaled, propriété connexion à un 46-3 accès aux données 25-1
TCustomForm 11-9 serveur, applications accès non autorisé 17-7
ScanLine, propriété extraction de données 21-16, attachement 17-8–17-9
bitmap 7-9 21-19 documents Active et 44-17
bitmap, exemple 7-19 interfaces 30-2 noms 14-23
ScktSrvr.exe 14-10, 14-14, 14-23 services 30-1 serveurs en processus 44-6
SCM 4-4 transactions 13-9 ActiveX 44-12
Screen, variable 5-3, 10-8 serveur, connexions 30-2, 30-3 ASP 51-3
scripts (URL) 29-2 numéros de port 30-5 serveurs hors processus 44-7
scripts de connexion 17-7 serveur, sockets 30-7–30-8 ASP 51-4
ScrollBars, propriété 2-24, 6-8 acceptation de clients 30-10 service
mémo, champs 26-11 acceptation de requêtes threads 4-6
SDK Microsoft Data client 30-7 Service Control Manager 4-4
Access 23-5 gestion d’événements 30-10 service d’annuaire 28-3
sections critiques 8-7 messages d’erreur 30-8 Service, propriété
précaution d’utilisation 8-8 socket Windows, objets 30-7, client, sockets 30-6
Sections, propriété 2-22 30-8 serveur, sockets 30-7
securité 17-7 spécification 30-6 services 4-3–4-8
applications multiniveaux 14-2 utilisation de threads 30-12 annuaire 28-2, 28-3–28-4
bases de données 12-4 serveurs ActiveX code exemple 4-4, 4-6
connexions Web 14-11, 14-24 bibliothèques de types 44-13 CORBA 28-2
dBase, tables 13-4 optimisation 44-15 demande de 30-6
DCOM 14-37 vérification de type 44-15 désinstallation 4-4
évolutivité et 12-9 serveurs Automation 44-10, implémentation 30-1–30-2, 30-7
MTS 14-6, 14-10, 50-12 44-11, 44-19 installation 4-4
Paradox, tables 13-4 accès aux objets 47-8 ports et 30-2
recensement pour les création 47-1, 47-9 propriétés de nom 4-8
connexions socket 14-10 test 47-6 réseau, serveurs 30-1
segments de ligne tester 51-5 services de support 1-3
connectés 7-10 serveurs COM 44-3, 44-5, 44-19 Session, composant 16-1, 16-2
SELECT, instructions 21-14, distants 44-7 Session, propriété 17-4
21-18 en processus 44-6 SessionName, propriété 16-4,
SelectAll, méthode 2-14 hors processus 44-7 17-4, 18-32, 18-33, 29-23
SelectCel,l méthode 42-4 serveurs COM et CORBA sessions 13-4, 16-1, 16-2, 17-10
SelectCell, méthode 41-13 combinés 28-5 activation 16-5, 16-6
Sélection de menu, boîte de serveurs d’applications 14-1, création 16-3–16-4, 16-18, 16-19
dialogue 5-26 14-13–14-21 décompte 16-18
contraintes de données 15-11 dénomination 16-4, 29-23
Selection, propriété 2-24
fournisseurs de données 15-1 désactivation des
Sélectionner un menu, connexions 16-6
commande (menu identification 14-22
état en cours 16-5
Concepteur) 5-25, 5-26
Index I - 35
SQL, serveurs 12-3 support développeur 1-3 dénomination 20-3
contraintes 19-25 support technique 1-3 droits d’accès 20-5
SQL, standards 21-4 Suppression de modèles, boîte en lecture seule 20-5
serveurs distants 21-19 de dialogue 5-28 extraction de données 20-12,
SQLPASSTHRUMODE 13-10 suppressions en cascade 15-4 20-21, 21-1
squelettes 28-2, 28-3, 28-8 Supprimer les modèles, insertion
marshaling 28-3, 28-8 commande (menu d’enregistrements 18-25–
Standard, page de la palette des Concepteur) 5-26, 5-28 18-26, 18-28
composants 2-11 Supprimer, commande (menu Interbase 12-17
StartTransaction, méthode 13-7 Concepteurr) 5-25 maître/détail, relations 20-28–
State, propriété 2-18, 23-5 20-29
surcharge
colonnes de grille 26-19 mise à jour des données avec
méthodes 32-9, 37-3, 41-11
grilles 26-19, 26-22 des 25-24
Suspend, méthode 8-12
State, propriété interne ouverture 20-4
Sybase, pilote parcours des 20-5–20-9
ADO 23-15 déploiement 11-6
restructuration 13-11
StatusCode, propriété 29-16 synchronisateur à écriture spécification du type 20-3
STDVCL40.DLL 11-6 exclusive et à lecture suppression 20-18
Step, propriété 2-24 multiple 8-8 suppression
StepBy, méthode 2-24 précaution d’utilisation 8-8 d’enregistrements 20-18
StepIt, méthode 2-24 synchronisation des précaution 20-18
stockages de données 23-3 données 20-27 synchronisation 20-27
stored, directive 33-12 sur plusieurs fiches 26-7, 26-8 tri de données 20-10–20-12
StoreDefs, propriété 20-20 Synchronize, méthode 8-4 avec des index
StoredProcName, propriété 22-4 système d’aide 38-4 secondaires 20-10
StrByteType 3-31 boutons outils 5-38 vidage 20-18
Stretch, propriété 26-12 fichiers 38-4 tables ADO 12-17
StretchDraw, méthode 7-5, 36-3, mots clés 38-5 présentation 23-21
36-7 Système, page de la palette des utilisation 23-21
string, mot réservé 3-28 composants 2-11 tables en lecture seule 20-5
type par défaut 3-26 systèmes de gestion de bases de tables IB 12-17
VCL, types de propriété 3-28 données 14-1 tables imbriquées 12-16, 19-30–
Strings, propriété 2-35 relationnelles 12-3 19-31, 20-29
Structured Query systèmes hôtes à localisations client, ensembles de
Language 12-3 multiples 28-21 données 14-30
stThreadBlocking, fichiers linéaires 24-4
constante 30-10 T maître/détail, relations 14-30
stubs 28-2, 28-3, 28-8, 28-13, tables non indexées 18-26, 18-28
28-13–28-14 Table , balise HTML parcours 20-6
création 28-14 (<TABLE>) 29-20 tables Oracle 22-19
marshaling 28-3 table, composants 12-16, 20-2 tables problématiques 20-26
Style, propriété 2-19, 2-20, 2-25, TableAttributes, propriété 29-25 TableType, propriété 20-3
14-42 tableau, champs 19-29 TabOrder, propriété 2-13
boîtes à options 26-13 tableaux 33-3, 33-9 Tabs, propriété 2-22
boutons outils 5-36 sécurisés 49-25 TabStop, propriété 2-13
crayons 7-5 tableaux grilles 2-24 TAction 5-39
pinceaux 7-8 TableName, propriété 23-22 TActionLink 5-39
variants dessinés par le tables 12-15, 20-1 TActionList 5-39
propriétaire 6-13–6-14 affichage dans les grilles 26-19 TActiveXControl 48-2
StyleRule, propriété 14-42 ajout 20-2–20-4 TADOCommand 23-1, 23-24,
Styles, propriété 14-42 basées sur ADO 12-17 23-28, 23-30
StylesFile, propriété 14-43 changement de nom 20-18 TADOConnection 23-1, 23-3,
substitution des paramètres composants d’aide à la 23-4, 23-6, 23-11, 23-14, 23-20,
(SQL) 25-17, 25-22 décision et 27-3
23-21, 23-23, 23-24, 23-25
Subtotals, propriété 27-14 création 13-11, 13-16, 20-19
se connecter à un stockage de
Supplément, page de la palette définitions des champs et des
données 23-3
des composants 2-11 index 20-20
TADODataSet 13-14, 23-20
Index I - 37
TextRect, méthode 7-5, 36-3 mise en mémoire cache 30-15 TMemIniFile 2-37
TextWidth, méthode 7-5, 36-3 objets distribués 8-13 TMemoField 19-2
TField 19-1 priorités 8-1, 8-3 TMemoryStream 2-38
ajout 19-1–19-5 redéfinition 8-11 TMessage 37-4, 37-6
événements 19-20 renvoi de valeurs 8-9 TMetafile 36-4
méthodes 19-20 sections critiques 8-7 TMethodProperty, type 38-8
propriétés 19-3, 19-14–19-19 serveur, sockets 30-12, 30-14– TMsg 5-5
exécution 19-16 30-15 TMTSDataModule 14-5
TFieldDataLink 42-5 serveurs de messagerie 8-12 TMultiReadExclusiveWriteSync
TFiler 3-41 serveurs en processus 8-14
hronizer 8-8
TFileStream 2-38 sessions de base de données
TNotifyEvent 34-8
E/S de fichier 3-41–3-45 et 13-5, 16-3
utilisation avec des sockets
TNumericField 19-2
TFloatField 19-2 TObject 2-7, 32-4
TFloatProperty, type 38-8 client 30-14
utilisation avec des sockets Top, propriété 2-12, 5-3, 5-33
TFontNameProperty, type 38-8 TopRow, propriété 2-24
TFontProperty, type 38-8 serveur 30-15
utilisation de listes 8-5 TOrdinalProperty, type 38-8
TForm touches accélératrices 5-21
VCL, thread 8-4
barres de défilement 2-15 TPageProducer 29-19
verrouillage des objets 8-7
TForm, composant 2-3 TPanel 5-31
threads de service 4-6
TFrame 5-14 TParameter 23-19, 23-31
threads en suspens 8-12
TGraphic 36-4 TPersistFormat, type 23-18
threads multiples
TGraphicControl 31-4, 40-2 tpHigher, constante 8-3
attente de 8-10
thread VCL principal 8-4 tpHighest, constante 8-3
threadvar 8-5
OnTerminate, événement 8-6 TPicture, type 36-4
THTMLTableAttributes 29-25
Thread, boîte d’état 8-15 tpIdle, constante 8-3
THTMLTableColumn 29-25
thread, fonction 8-4 tpLower, constante 8-3
TickMarks, propriété 2-15
thread, objets 8-2 tpLowest, constante 8-3
définition 8-2
TickStyle, propriété 2-15
TIcon 36-4 tpNormal, constante 8-3
limites 8-2
tiDirtyRead, constante 13-8 TPopupMenu 5-38
ThreadID, propriété 8-15 TPropertyAttributes 38-11
threads 8-1–8-15 TImage
dans les cadres 5-16 TPropertyEditor, classe 38-8
accès aux données,
TImageList 5-35 tpTimeCritical, constante 8-3
composants 8-5
arrêt 8-6, 8-12 TIniFile 2-37 TQuery 2-40, 21-1
TIntegerField 19-2 ajout 21-4
attente d’événements 8-10
TIntegerProperty, type 38-8, ensembles de données de
attente de 8-9
38-10 décision et 27-6
bibliothèques 8-14
blocage de l’exécution 8-7 TInterfacedObject 3-23 TQueryTableProducer 29-26
boucle des messages et 8-5, dérivation de 3-19 traduction 10-9
8-13 implémentation de traduction de chaînes de
client, sockets 30-12, 30-13– IUnknown 3-19 caractères 10-2, 10-8, 10-10
30-14 liaison dynamique 3-19 conversions sur 2 octets 10-3
COM 8-13 tiReadCommitted, traitement distribué des
coordination 8-4, 8-7–8-11 constante 13-8 données 14-2
CORBA 8-13 tiRepeatableRead, transactions 12-5, 13-5–13-10
création 8-11 constante 13-8 abandon 13-8
espace de processus 8-4 TISAPIApplication 29-5 applications
éviter les accès simultanés 8-7 TISAPIRequest 29-5 multiniveaux 14-29
exécution 8-11 TISAPIResponse 29-5 attributs
graphiques, objets 8-5 Title, propriété objets MTS 50-17, 50-19
identificateurs 8-15 grilles de données 26-25 changements non validés
initialisation 8-3 TKeyPressEvent, type 34-4 et 13-8
ISAPI/NSAPI, contrôles 13-6
TLabel 31-4
programmes 29-7, 29-23 démarrage 13-7
.TLB, fichiers 44-15, 49-37
libération 8-3 durée 13-7
TLIBIMP 44-16 implicites 13-6
limites du nombre de 8-11 TListBox 31-3 locales 13-10
Index I - 39
UnregisterPooled,
procédure 14-8
V verrouillage des objets
imbrication des appels 8-7
UnRegisterTypeLib, fonction $V, directive de threads 8-7
désinstallation des compilation 3-35 verrous 20-5
bibliothèques de valeurs 33-2 verrous exclusifs 20-5
désinstallation 44-15 booléennes 33-2, 33-11, 42-4 VertScrollBar 2-15
UPDATE, instructions 21-14, default, propriété 33-11 vidéo analogique 7-34
21-15, 25-13 données par défaut 19-25, violations d’accès
Update, méthode 26-12 chaînes 3-32
actions 5-44 null 18-28, 20-14 violations de clé 20-26
UpdateCalendar, méthode 42-4 portées et 20-14 virtual
UpdateMode, propriété 15-8 propriété par défaut 33-8 directive 32-9
UpdateObject, propriété 18-34, redéfinition 39-2, 39-3 tables de méthode 32-9
25-13 test 33-7 virtuelles
transtypage 25-20 valeurs de référence 26-21 méthodes 32-9, 35-4
UpdateRecordTypes, valeurs des axes 27-17 éditeurs de propriétés 38-9–
propriété 18-34, 25-10, 25-11 valeurs littérales 19-25 38-10
UpdatesPending, valeurs logiques 26-2, 26-16 propriétés comme 33-2
propriété 18-34, 25-4 valeurs récapitulatives 27-21 visibilité 2-8
UpdateSQL, éditeur 25-16 agrégats maintenus 24-13 Visible, propriété 19-16
UpdateStatus, propriété 18-34, graphes de décision 27-17 barres d’outils 5-38, 5-39
25-12 références croisées 27-3 barres multiples 5-38
UpdateTarget, méthode 5-44 validation menus 5-29
URI d’enregistrements 26-5 VisibleButtons, propriété 26-33,
URL ou 29-2 grilles de données 26-28 26-34, 26-35
URL 29-2 validation des saisies de VisibleColCount, propriété 2-24
bibliothèques javascript 14-36, données 19-20 VisibleRowCount,
14-37 validation des transactions 13-7, propriété 2-24
connexions Web 14-24 13-8 VisiBroker ORB 14-15
IP, adresses 30-4 Value, propriété 19-21 VisualSpeller Control 11-3
noms d’hôte 30-4 ValueChecked, propriété 26-17 volets 2-22
URI ou 29-2 Values, propriété 26-18 ajout de turboboutons 5-33
Web, navigateurs 29-3 ValueUnchecked, aligné sur le haut de la
URL, propriété 29-14 propriété 26-17 fiche 5-32
USEPACKAGE, macro 9-8 var, mot réservé vtable 44-5
uses, clause 2-7 gestionnaires vtables
éviter les références d’événements 34-4 pointeur d’interface COM 44-5
circulaires 5-2 variables 21-7 vues arborescentes 2-20
inclusion de paquets 9-4 déclaration
modules de données exemple 2-8
et objets 2-8–2-9
W
accès depuis des fiches 2-39
usInserted, constante 25-12 variables d’environnement WaitFor, méthode 8-9, 8-10
usModified, constante 25-12 CORBA 28-18 WaitForData, méthode 30-13
usUnmodified, constante 25-12 variables locales aux WantReturns, propriété 2-14
utilisateur, interfaces 12-13– threads 8-5 WantTabs, propriété 2-14
12-18 OnTerminate, événement 8-6 contrôles d’édition de texte
enregistrement unique 12-13 variants 18-17, 18-18, 19-23 formaté 26-11
enregistrements CORBA 28-14 mémo, champs 26-10
multiples 12-14 TAny 28-14 .WAV, fichiers 7-34
isolement 12-8 VCL 31-1–31-2 $WEAKPACKAGEUNIT,
Utiliser unité, commande présentation 2-1 directive de compilation 9-12
(Fichier) 5-2 propriétés de type chaîne 3-28 Web
Utiliser unité, menu thread principal 8-4 base de données 14-32–14-44
Fichier 2-40 VCL30, paquet 9-1, 9-10 connexions 14-24
Utiliser, référentiel d’objets 2-42 PENWIN.DLL 9-13 Web, applications
déploiement 11-7
objet 29-7
Index I - 41
I-42 Guide du développeur